python中的默认参数陷阱


前言

一直以来,为了函数或者类的方便使用,经常使用默认参数来简化使用,不过最近发现这种方法中存在一个官方陷阱,详见下文。

1. 问题描述

现有下面一个例子:

1
2
3
4
5
6
7
def add_to(v, target=[]):
target.append(v)
return target
add_to(1)
add_to(2)
r = add_to(3)
print(r) # [1, 2, 3]

我们可以看到,我们想要的输出应该是[3],然后实际上就出乎我们的意料,原因在于,python对于函数中的默认参数,会在编译的时候申请一块内存,如果默认参数是可变参数,那么重复调用该函数或者类初始化,会共用这一块内存,从而使得实际输出与理论输出不一致。

2.解决方案

  • 采用不可变参数作为默认参数

    不可变参数包含常数元组None等等,这些参数作为默认参数后,重复调用会重复申请一块空间,而对于可变参数——·列表`,则是会共用空间。

  • 初始化参数

    每次调用函数或者类构造函数时,都给带有可变参数的默认参数重新赋值,即可重新申请空间。

  • 内部判断

    在函数内部判断,从而根据不同的输入条件,赋予不同的值,这样就避免了默认参数的空间申请。如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    def add_to(v, target=[]):
    if target == []:
    target = []
    target.append(v)
    return target
    add_to(1)
    add_to(2)
    r = add_to(3)
    print(r) # [3]

下面给出网上的示例图:

img

img


-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!