[问题][python 实践]Default argument value is mutable (默认参数是可变的)
1 class Test(object): 2 def func(self, data=[]): 3 print('[func]data id: {}'.format(id(data))) 4 data.append('end') 5 return data 6 7 print('异常情况:') 8 print('-----test1-----') 9 test1 = Test() 10 print(test1.func()) 11 12 print('-----test2-----') 13 test2 = Test() 14 print(test2.func()) 15 16 print('-----test3-----') 17 test3 = Test() 18 print(test3.func(data=[1, 2]))
问题:
“异常情况”中,test2 输出了 2 个end,原因是什么呢?
原因:
Python函数的参数默认值,是在编译阶段就初始化的,并不是每调用一次函数都会重新初始化。
故:test1 和 test2 中data的地址一样的,append了 2 次,就出现了 2 个end
参考资料:
1、The Hitchhiker’s Guide to Python
Python’s default arguments are evaluated once when the function is defined, not each time the function is called (like it is in say, Ruby). This means that if you use a mutable default argument and mutate it, you will and have mutated that object for all future calls to the function as well.
The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls
解决方案:
参考 func_new
1 class Test(object): 2 def func_new(self, data=None): 3 if data is None: 4 data = [] 5 print('[func_new]data id: {}'.format(id(data))) 6 data.append('end') 7 return data 8 9 print('正常情况:') 10 print('-----test4-----') 11 test4 = Test() 12 print(test4.func_new()) 13 14 print('-----test5-----') 15 test5 = Test() 16 print(test5.func_new()) 17 18 print('-----test6-----') 19 test6 = Test() 20 print(test6.func_new(data=[1, 2]))