关于oop:具有默认参数的python类构造函数

Python class constructor with default arguments

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument

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

我有以下课程:

1
2
3
4
5
6
7
8
9
class Zoo:
    def __init__(self,alist=[]):
        self.animals = alist

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

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

当我做以下工作时,

1
2
3
4
5
6
7
8
9
10
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不是空名单?

谢谢,马蒂亚斯


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

1
2
3
4
5
6
7
8
9
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)

对于所有实例,默认参数列表都是相同的对象,因此将其分配给成员只会分配对同一对象的引用。

下面是一个例子:

1
2
3
4
5
6
7
8
9
10
>>> class foo():
...   def __init__(self, x = []):
...       print id(x)
...
>>> x = foo()
140284337344168
>>> y = foo()
140284337344168
>>> z = foo()
140284337344168

您可以看到,x在所有情况下都是相同的对象。