##language:zh #pragma section-numbers off ##含有章节索引导航的 ZPyUG 文章通用模板 <> ## 默许导航,请保留 <> = 经典Py形参陷井 = {{{ iasybvm reply-to python-cn@googlegroups.com to python-cn date Sat, Jan 30, 2010 at 19:55 subject [CPyUG] 一段灵异代码,汗。。。 }}} ##startInc == 现象 == {{{ #!python class Category(object): def __init__(self, id): self.children = [] self.id = id def recurse_for_children(self, node): children = [] children.append(node) for child in node.children: if child != self: children_list = self.recurse_for_children(child) children.append(children_list) return children def recurse_normal_children(self, node, children=[]): children.append(node) for child in node.children: if child != self: self.recurse_normal_children(child, children) return children def __str__(self): return "Category %d" % self.id def get_flat_list(sequence): result = [] for item in sequence: if type(item) == types.ListType: result.extend(get_flat_list(item)) else: result.append(item) return result }}} get_flat_list和 recurse_for_children 加起来应该和get_normal_children等价的。 但是,结果却并不是这样,get_normal_children会给出多得多的结果。 {{{ >>> def recurse_for_normal(node, children=[]): ... children.append(node) ... for child in node.children: ... recurse_for_normal(child, children) ... 这一个好一些。 为什么会这样啊? }}} === 原因分析 === {{{ HYRY reply-to python-cn@googlegroups.com to python-cn`CPyUG`华蟒用户组 date Sat, Jan 30, 2010 at 20:59 }}} Python的经典陷坑: * 缺省值如果为列表这样的可变对象的话,只会初始化一次,并非每次调用函数都会将children 初始化为[]。 {{{ def recurse_normal_children(self, node, children=[]): }}} 看下面的例子: {{{ #!python def test(t=[]): t.append(2) print t test() test() }}} 输出为 {{{ [2] [2, 2] }}} 设置初始值是在函数创建时,而不是在函数调用时。 {{{ #!python def test(tmp=[1]): return tmp print test.func_defaults print id(test.func_defaults[0]) print id(test()) print id(test()) }}} 输出为 {{{ ([1],) 57736168 57736168 57736168 }}} 也就是说每次调用test函数并没有创建一个新列表,而是直接使用 创建函数时所创建的那个缺省值列表。因此输出的三个id是一样的。 * `即在创建函数时以及将缺省值求出来放到func_defaults中去了` === 一般处置 === {{{ KDr2 sender-time Sent at 21:03 (GMT+08:00). Current time there: 9:22 PM. ✆ reply-to python-cn@googlegroups.com to python-cn@googlegroups.com date Sat, Jan 30, 2010 at 21:03 }}} 嗯,一般是 {{{ def function(default_arg=None): if default_arg==None:default_arg=[] #.... }}} == PS:动态的参数 == {{{ 机械唯物主义 sender-time Sent at 21:09 (GMT+08:00). Current time there: 9:23 PM. ✆ reply-to python-cn@googlegroups.com to python-cn@googlegroups.com date Sat, Jan 30, 2010 at 21:09 }}} 还有就是动态建立function的时候,如果用到外面的变量,要传进去,不然就会被覆盖掉。 {{{ #!python for i in rannge(12): button = QPushButton("number: "+str(i+1)) def func(button=button): doSomething(button) connect(button, "clicked()", func) }}} ##endInc ---- '''反馈''' 创建 by -- ZoomQuiet [<>]