我在 Expert Python Programming 中读到了关于这种边缘情况的内容。检查这段代码:
def f(arg={}):
arg['3'] = 4
return arg
>>> print f()
{'3': 4}
>>> res = f()
>>> res['4'] = 'Still here'
>>> print f()
{'3': 4, '4': 'Still here'}
我不清楚为什么当 f
最后一次被调用时(在它的返回值被保存之后),而不是将 arg 分配给空字典(因为它是在没有参数的情况下调用的),它保留旧引用。
书中是这样说的:“如果在参数中创建了一个对象,那么如果函数返回该对象,参数引用将仍然存在”。
我理解“这就是它的工作方式”,但为什么呢?
最佳答案
因为默认参数仅在计算和创建函数时计算一次(它们是函数定义的一部分,可以通过 inspect.getargspec 获取,例如)。
因为它们是函数的一部分,所以对函数的每次调用都将具有默认值的相同实例。如果它是一个不可变的值,这不是问题,但一旦它是可变的,它就会成为一个问题。
给定类定义,类定义中存在相同的“特征”:
class A(object):
foo = {}
打电话
x = A()
y = A()
x.foo['bar'] = "baz"
...将使 y.foo['bar'] 计算为“baz”,因为 x 和 y 具有相同 foo。 这就是为什么成员初始化应该在 init 而不是类主体中完成。
关于Python - 入站出站参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9215343/