Python2.7中的staticmethod参数在调用之间保留值?

2024-04-24 09:48:47 发布

您现在位置:Python中文网/ 问答频道 /正文

Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument

在使用Python2.7时,我遇到了一些奇怪的行为,我不知道该如何解释,也不知道它是否存在于任何python文档中。使用代码

class MyClass:
@staticmethod
def func(objects=[], a=None, b=None):
    objects.append(a)
    print 'objects: %s'%objects
    print 'b: %s'%b


MyClass.func(a='one')
MyClass.func(a='two', b='foo')
MyClass.func(a='three')

我得到get输出

^{pr2}$

如您所见,该方法的第一个list参数(objects)在调用之间保留它的值。。新值被追加到最后一个列表中,即使在它的头声明中它有一个默认值[]。但最后一个参数(b)没有保留它的值,它会在调用之间重置为默认值。在

预期的(无论如何对我来说)是objects参数应该在对方法的任何调用中重置为它的默认值(就像b参数一样),但是这似乎没有发生,而且似乎只在第一次调用时发生。在

有人能解释这种行为吗?这是python版本中的一个bug还是它的预期行为?可能是因为列表引用在调用之间被保留,但字符串变量(b)不是?我被这种行为弄糊涂了。在

谢谢


Tags: the方法innone列表参数objectsmyclass
2条回答

这种行为是众所周知的,许多人将其视为一种特性,而不是特定于staticmethod。它适用于所有功能。将可变对象指定为参数的默认值时会发生这种情况。在

请参见StackOverflow:Default Argument Gotchas / Dangers of Mutable Default arguments

如果您了解易变性与不变性的关系,那么可以这样考虑函数/方法:

  • 当它被定义时,默认参数值被赋值
  • 当它被调用时,主体被执行,如果它改变了可变的默认参数值,那么在以后的每次调用中都会使用更改后的值,其中默认参数值没有通过提供不同的值来替代它来重写

它与静态方法无关。这是Python中非常常见的错误。在

Python中的函数是一类对象,而不仅仅是一段代码,因此在参数中分配给对象的空列表是附加到函数对象的实际列表。每次调用它并在该列表中添加内容时,您使用的是同一个列表。很容易看出事情是这样发生的:

>>> def func(x, objects=[]):
...     objects.append(x)
... 
>>> func(1)
>>> func.func_defaults
([1],)
>>> func(2)
>>> func.func_defaults
([1, 2],)
>>> func(3)
>>> func.func_defaults
([1, 2, 3],)

func_defaults是包含您设置的默认关键字参数的函数对象属性。看看名单是怎么回事,然后改了吗?在

正确的方法是:

^{pr2}$

相关问题 更多 >