今天我发现了一些我认为非常奇怪的事情。
>>> import StringIO
>>> def test(thing=StringIO.StringIO()):
... thing.write("test")
... print thing.getvalue()
...
>>> test()
test
>>> test()
testtest
>>> test()
testtesttest
>>> test()
testtesttesttest
>>> test()
testtesttesttesttest
在今天之前我会读到这行
def test(thing=StringIO.StringIO()):
为:
声明一个函数,其kwargs字典在被调用时默认为新的
StringIO
作为键'thing'的值,并将其添加到当前作用域。
但是从示例中我认为它更像是:
声明一个函数。构造一个包含新
StringIO
的字典。将此值分配给函数的默认kwargs,并将该函数添加到当前范围。
这是正确的解释吗?对于默认的kwargs,还有其他问题需要注意吗?
答案 0 :(得分:4)
你的第二个定义是完全正确的。任何可变对象都会发生此行为。常见的习语是使用None
作为警卫。
def test(thing=None):
if thing is None:
thing = StringIO.StringIO()
thing.write("test")
print thing.getvalue()
有关详细信息,请参阅Python 2.x gotcha's and landmines上的此答案。
答案 1 :(得分:2)
是的,第二种解释是正确的。这是Python中的陷阱之一。这里已经多次讨论过了。例如,请参阅:"Least Astonishment" and the Mutable Default Argument