2007年06月26日 星期二 09:04
請先看代碼(簡化的模型):
01. class A():
02. def __init__(self, id, choices = [], flag = 0):
03. self._flag = flag
04. self.items = []
05.
06. self.foo(choices)
07.
08. def foo(self, choices):
09. ch = choices[:]
10. if self._flag == 1:
11. ch.insert(0, '--- all ---')
12. choices.insert(0, '--- all ---')
13. elif self._flag == 2:
14. ch.insert(0, '')
15. choices.insert(0, '')
16. else:
17. pass
18. self.items.extend(ch)
19.
20. t1 = A( 1, [1,2],1)
21. t2 = A( 1,flag = 1)
22. t3 = A( 1,flag = 1)
23. t4 = A( 1,flag = 1)
24. t5 = A( 1, ['a','b','c'], 1)
25. print t1.items,'\n',t2.items,'\n',t3.items,'\n',t4.items,'\n',t5.items
26.
27. ## bad answer
28. ##['--- all ---', 1, 2]
29. ##['--- all ---']
30. ##['--- all ---', '--- all ---']
31. ##['--- all ---', '--- all ---', '--- all ---']
32. ##['--- all ---', 'a', 'b', 'c']
33. ## good answer
34. ##['--- all ---', 1, 2]
35. ##['--- all ---']
36. ##['--- all ---']
37. ##['--- all ---']
38. ##['--- all ---', 'a', 'b', 'c']
最開始時,沒有變量ch,即無第9,11,14行,第18行為 self.items.extend(choices),結果在實例化時,如果前一個實例缺省choices參數,則本實例self.items中的元素就會多'--- all ---'.
后來才發現是foo()中choices的原因.增加了第9行等,就能得到我想要的結果.我想一定是foo()中的choices作用域有問題,像是變成了類屬性,但用self.__class__.choices又會引發異常.
困惑中,特來請各位指點一二!
___________________________________________________________
抢注雅虎免费邮箱3.5G容量,20M附件!
http://cn.mail.yahoo.com
-------------- 涓嬩竴閮ㄥ垎 --------------
一个HTML附件被移除...
URL: http://python.cn/pipermail/python-chinese/attachments/20070626/a0855b5a/attachment.html
2007年06月26日 星期二 09:28
当一个函数的参数的缺省值为一个可变对象时,如list,dict等,由于在编译源码时它会只执行一次,因此这个值就会保存下来,而不是象想象得很次调用都重新启始化。就如同import模块,只会导入一次一样。所以如果你在函数中修改了这个可变值,那么就会影响到后面的调用。所以要么象你做的一样,每次创建一个新的对象,要么不要使用可变对象作为缺省值,这样就不会有问题了。 -- I like python! UliPad <>: http://wiki.woodpecker.org.cn/moin/UliPad My Blog: http://www.donews.net/limodou
2007年06月28日 星期四 13:18
嗯哪!所以我觉得在 Python 中下面两种定义一般来说是很危险的:
class Foo:
bar = []
...
def foo(bar=[]...):
...
除非知道自己在干什么,最好:
def foo(bar=None,...):
if bar is None: bar = []
...
在 07-6-26,limodou<limodou在gmail.com> 写道:
> 当一个函数的参数的缺省值为一个可变对象时,如list,dict等,由于在编译源码时它会只执行一次,因此这个值就会保存下来,而不是象想象得很次调用都重新启始化。就如同import模块,只会导入一次一样。所以如果你在函数中修改了这个可变值,那么就会影响到后面的调用。所以要么象你做的一样,每次创建一个新的对象,要么不要使用可变对象作为缺省值,这样就不会有问题了。
>
> --
> I like python!
> UliPad <>: http://wiki.woodpecker.org.cn/moin/UliPad
> My Blog: http://www.donews.net/limodou
> _______________________________________________
> python-chinese
> Post: send python-chinese在lists.python.cn
> Subscribe: send subscribe to python-chinese-request在lists.python.cn
> Unsubscribe: send unsubscribe to python-chinese-request在lists.python.cn
> Detail Info: http://python.cn/mailman/listinfo/python-chinese
Zeuux © 2025
京ICP备05028076号