>>> def fun(l=[]):
... l.append(1)
... print(l)
...
>>> fun()
[1]
>>> fun()
[1, 1]
>>> fun([])
[1]
>>> fun()
[1, 1, 1]
>>>
第二个输出是预期的,解释如下-“在定义函数时将创建一个新列表,并且在每个后续调用中使用相同的列表。” (来源:https://docs.python-guide.org/writing/gotchas/)。但是,当显式传递一个空列表作为参数时,该函数的列表应重置为[],最后的输出应为[1,1],而不是[1,1,1]。
来自同一文档。
Python的默认参数在函数为定义,而不是每次调用该函数时(例如,红宝石)。这意味着,如果您使用可变的默认参数,对其进行突变,您将并且已经为以后的所有调用对该对象进行了突变以及功能。
要确认这一点,您可以打印默认参数的id
。默认参数对将来所有对该函数的调用使用相同的列表对象。但是在fun([])
传递新列表对象到l
的地方(因此,不使用默认参数的值)
>>> def fun(l=[]):
... l.append(1)
... print(l, f"id={id(l)}")
...
>>> fun()
[1] id=4330135048
>>> fun()
[1, 1] id=4330135048
>>> fun([])
[1] id=4330135944
>>> fun()
[1, 1, 1] id=4330135048
该文档说,'Python的默认参数在定义函数时被评估一次,而不是在每次调用函数时被评估'。是的。从文档中了解到,一旦定义了函数,列表也会创建并存储值,但是在您调用函数的情况下,它将返回已经定义的包含列表的函数的值。调用func([])
时,您将传递空列表作为已定义并存储列表值的参数。它返回当前值,但不会再次存储该值并重置前一个值。因此,当您再次调用func()
时,它将返回已经存储的列表项目。