1

嗨,我是 python 新手。有人可以解释以下两段代码如何给出不同的输出吗?每次调用函数时都会定义函数吗?

 def f(a, L=[]): 
     L.append(a) 
     return L



def f(a, L=None):
     if L is None:
         L = []
     L.append(a)
     return L

在运行中

 print f(1)
 print f(2)
 print f(3)

我分别得到这些输出

 [1]
 [1, 2]
 [1, 2, 3]



 [1]
 [2]
 [3]
4

3 回答 3

2

对于新的 Python 开发人员来说,这是一个非常常见的“陷阱”。在第一个示例中,每次调用没有第二个参数的函数时,似乎都应该创建一个新的空列表。它不是。创建函数对象时会创建一个列表,这基本上是在加载 python 脚本或您在交互式 shell 中完成输入函数时。然后,此列表用于函数的每次调用,因此您会看到累积。

第二种是解决这个问题的标准方法,每次调用函数时都创建一个新的列表实例,而无需第二个参数。

在幕后,Python 将它在函数定义中找到的任何默认值放入函数的一个名为defaults的属性中。您可以看到在交互式 shell 中的调用之间如何存在相同的实例:

>>> def f(a,b=[]):
...     b.append(a)
>>> f.__defaults__
([],)
>>> f(1)
>>> f.__defaults__
([1],)
>>> f(2)
>>> f.__defaults__
([1,2],)
于 2013-07-17T14:59:16.797 回答
0

python 中的默认参数在函数声明点进行评估 - 当它第一次被解释器看到时。

在您的第一个片段中,L参数是“给定”一个列表作为默认值,因此附加了值。

在第二个片段中,L总是None在进入函数时,所以每次都重新创建。

于 2013-07-17T15:01:47.983 回答
0

定义函数时会评估函数默认参数。在您的情况下def f(a, L=[]):,创建一个空列表,然后在每次调用不带L参数的函数时传递该列表。所以对函数的每次调用都在同一个列表上运行,这就是为什么它每次都给出不同的输出。

在您的第二个函数中,每次调用该函数时都会创建一个空列表,因此它可以按预期工作。

于 2013-07-17T15:05:52.347 回答