简单的python oo问题

Ale*_*x K 4 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
Run Code Online (Sandbox Code Playgroud)

unu*_*tbu 12

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

简而言之,当你定义

def __init__(self,a=[])
Run Code Online (Sandbox Code Playgroud)

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

解决这个问题的典型方法是:

class A(object):
    def __init__(self, a=None):
        self.a = [] if a is None else a
Run Code Online (Sandbox Code Playgroud)

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


pup*_*eno 6

Python中的默认参数,如:

def blah(a="default value")
Run Code Online (Sandbox Code Playgroud)

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

def blah(a=None):
  if a is None
    a = []
Run Code Online (Sandbox Code Playgroud)

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

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