Python类构造函数的默认参数

15

可能是重复问题:
“Least Astonishment” in Python: The Mutable Default Argument

有人能解释一下以下奇怪的行为吗?

我有以下这个类:

class Zoo:
    def __init__(self,alist=[]):
        self.animals = alist

    def __len__(self):
        return len(self.animals)

    def add(self,a):
        self.animals.append(a)

当我执行以下操作时,

In [38]: z=Zoo()
In [39]: z.add(2)
In [40]: z.add(23)
In [41]: len(z)
Out[41]: 2

In [42]: z2=Zoo()

In [43]: len(z2)
Out[43]: 2
为什么 z2.animals 不是个空列表?
谢谢,Matthias

2
也许他不知道该搜索什么?有时候,如果你不知道术语,很难想出正确的搜索词。 - hopla
2个回答

16

你正在更改构造函数中的默认参数(你只是将对同一列表的引用复制到每个实例中)。 您可以按照以下方式修复此问题:

class Zoo:
    def __init__(self,alist=None):
        self.animals = alist or []

    def __len__(self):
        return len(self.animals)

    def add(self,a):
        self.animals.append(a)

7
默认参数列表是所有实例的相同对象,因此将其分配给成员只会分配对同一对象的引用。
下面是一个例子:
>>> class foo():
...   def __init__(self, x = []):
...       print id(x)
... 
>>> x = foo()
140284337344168
>>> y = foo()
140284337344168
>>> z = foo()
140284337344168

您可以看到,所有实例中的x是同一个对象。

一个混淆且常见的误解的绝佳例证! - Gwyn Howell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接