4

看看这个简单的例子。我不太明白为什么 o1 打印两次“Hello Alex”。我认为由于默认 self.a 总是重置为空列表。有人可以向我解释这里的理由是什么吗?非常感谢。

class A(object):
        def __init__(self, a=[]):
            self.a = a

o = A()
o.a.append('Hello')
o.a.append('Alex')
print ' '.join(o.a)

# >> prints Hello Alex

o1 = A()
o1.a.append('Hello')
o1.a.append('Alex')
print ' '.join(o1.a)

# >> prints Hello Alex Hello Alex
4

2 回答 2

12

阅读这个关于可变默认函数参数的陷阱: http ://www.ferg.org/projects/python_gotchas.html

简而言之,当你定义

def __init__(self,a=[])

self.a 引用的列表默认只定义一次,在定义时,而不是运行时。因此,每次调用o.a.appendoro1.a.append时,您都在修改同一个列表。

解决此问题的典型方法是:

class A(object):
    def __init__(self, a=None):
        self.a = [] if a is None else a

通过self.a=[]进入__init__函数体,在运行时(每次__init__调用)创建一个新的空列表,而不是在定义时。

于 2010-04-19T13:24:25.293 回答
6

Python 中的默认参数,例如:

def blah(a="default value")

评估一次并在每次调用中重复使用,因此当您修改 a 时,您会全局修改 a。一个可能的解决方案是:

def blah(a=None):
  if a is None
    a = []

您可以在以下位置阅读有关此问题的更多信息:http ://www.ferg.org/projects/python_gotchas.html#contents_item_6

基本上,永远不要在参数的默认值上使用可变对象,例如列表或字典。

于 2010-04-19T13:24:59.067 回答