Python论坛  - 讨论区

标题:[python-chinese] 變量作用域的問題

2007年06月26日 星期二 09:04

wayne awon wjawon在yahoo.com.cn
星期二 六月 26 09:04:38 HKT 2007

請先看代碼(簡化的模型):
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 

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2007年06月26日 星期二 09:28

limodou limodou在gmail.com
星期二 六月 26 09:28:51 HKT 2007

当一个函数的参数的缺省值为一个可变对象时,如list,dict等,由于在编译源码时它会只执行一次,因此这个值就会保存下来,而不是象想象得很次调用都重新启始化。就如同import模块,只会导入一次一样。所以如果你在函数中修改了这个可变值,那么就会影响到后面的调用。所以要么象你做的一样,每次创建一个新的对象,要么不要使用可变对象作为缺省值,这样就不会有问题了。

-- 
I like python!
UliPad <>: http://wiki.woodpecker.org.cn/moin/UliPad
My Blog: http://www.donews.net/limodou

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2007年06月28日 星期四 13:18

Can Xue xuecan在gmail.com
星期四 六月 28 13:18:18 HKT 2007

嗯哪!所以我觉得在 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

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2025

    京ICP备05028076号