issue with mutable argument default values在Python中非常有名。基本上可变的默认值在定义时分配一次,然后可以在函数体中修改,这可能会让人感到惊讶。
今天在工作中我们正在考虑处理这个的不同方法(在针对None
的测试旁边显然是正确的方式......)我想出了一个{ {1}}您可以找到 here 或下面的解决方案(它只有几行,因此要点可能更具可读性)。
它基本上是这样的:
现在的问题是这种方法适用于Metaclass
和list
个对象,但它在某种程度上无法用于其他可变的默认值,如dict
或set()
。 任何想法为什么?
随意测试此代码。唯一的非标准dep。是六(pip安装六)所以它在Py2和3中工作。
bytearray()
答案 0 :(得分:3)
您现在的代码实际上是按照您的期望进行的。调用时,将默认值的新副本传递给函数。但是,由于您对此新值不执行任何操作,因此在下次调用时垃圾收集并且内存可以立即重新分配。
因此,你不断得到id()
。
不同时间点的两个对象的id()
相同的事实并不表示它们是同一个对象。
要查看此效果,请更改您的功能,以便使用会增加其引用计数的值执行某些操作,例如:
class ImmutableDefaultArgumentsObject(ImmutableDefaultArgumentsBase):
cache = []
def function_a(self, mutable_default_arg=set()):
print("function_b", mutable_default_arg, id(mutable_default_arg))
self.cache.append(mutable_default_arg)
现在运行代码将提供:
function_b set() 4362897448
function_b set() 4362896776
function_b set() 4362898344
function_b set() 4362899240
function_b set() 4362897672