我今天遇到了一个有趣的python bug,其中实例化一个类似乎反复出现状态.在以后的实例化调用中,已经定义了变量.
我将问题归结为以下类/ shell交互.我意识到这不是初始化类变量的最佳方法,但它肯定不应该像这样.这是一个真正的错误还是这个"功能"?:d
tester.py:
class Tester():
def __init__(self):
self.mydict = self.test()
def test(self,out={}):
key = "key"
for i in ['a','b','c','d']:
if key in out:
out[key] += ','+i
else:
out[key] = i
return out
Python提示:
Python 2.6.6 (r266:84292, Oct 6 2010, 00:44:09)
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
>>> import tester
>>> t = tester.Tester()
>>> print t.mydict
{'key': 'a,b,c,d'}
>>> t2 = tester.Tester()
>>> print t2.mydict
{'key': 'a,b,c,d,a,b,c,d'}
Sti*_*gma 11
几乎所有Python用户都遇到过一次或两次这样的功能.主要用于缓存等,以避免重复冗长的计算(简单的记忆,真的),虽然我相信人们已经找到了它的其他用途.
原因是def语句只执行一次,即定义函数时.因此,初始化值仅创建一次.对于引用类型(与不可更改的不可变类型相反),如列表或字典,这最终会成为一个可见且令人惊讶的陷阱,而对于值类型,它会被忽视.
通常,人们会这样解决:
def test(a=None):
if a is None:
a = {}
# ... etc.
Run Code Online (Sandbox Code Playgroud)
一般来说,默认方法参数不应该是可变的。而是这样做:
def test(self, out=None):
out = out or {}
# other code goes here.
Run Code Online (Sandbox Code Playgroud)
有关为什么需要这样做以及为什么它是 Python 语言的“功能”而不是错误的更多详细信息,请参阅这些链接。