简单的python oo问题

时间:2010-04-19 13:22:40

标签: python arguments mutable

看看这个简单的例子。我不太明白为什么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

2 个答案:

答案 0 :(得分:12)

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

简而言之,当您定义

def __init__(self,a=[])

默认情况下,self.a引用的列表仅在定义时定义一次,而不是在运行时定义。因此,每次拨打o.a.appendo1.a.append时,都会修改相同的列表。

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

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

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

答案 1 :(得分:6)

Python中的默认参数,如:

def blah(a="default value")

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

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

您可以在http://www.ferg.org/projects/python_gotchas.html#contents_item_6

上详细了解此问题

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