Python base classes share attributes?
本问题已经有最佳答案,请猛点这里访问。
test.py中的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Base(object): def __init__(self, l=[]): self.l = l def add(self, num): self.l.append(num) def remove(self, num): self.l.remove(num) class Derived(Base): def __init__(self, l=[]): super(Derived, self).__init__(l) |
python shell会话:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Python 2.6.5 (r265:79063, Apr 1 2010, 05:22:20) [GCC 4.4.3 20100316 (prerelease)] on linux2 Type"help","copyright","credits" or"license" for more information. >>> import test >>> a = test.Derived() >>> b = test.Derived() >>> a.l [] >>> b.l [] >>> a.add(1) >>> a.l [1] >>> b.l [1] >>> c = test.Derived() >>> c.l [1] |
我期待的是"C++类"行为,其中每个派生对象包含它自己的基类实例。还是这样吗?为什么每个对象看起来共享同一个列表实例?
你犯了一个常见的python新手错误。
请看我的答案:我应该如何在python中声明实例变量的默认值?
简单解释一下,python只解释一次类定义。这意味着在
然后,每次创建一个新类时,
Python的方式是这样的(部分代码):
1 2 3 4 | def __init__(self, arg=None): if arg is None: arg = [] self.arg = arg |
另外,您应该考虑使用比
这被称为可变的默认参数bug,通常由对Python不熟悉的人制造。当您将可变参数作为默认参数提供时,当需要使用默认参数时,相同的对象会在实例之间使用。"获得更好的理解"检查http://docs.python.org/tutorial/controlflow.html默认参数值中的重要警告部分
在代码中,实例A在其in it调用中使用了可变的默认参数(空列表对象),当您创建b的实例时,该实例又调用了base的in it方法,再次使用了与a在其in it中使用的对象完全相同的对象。在简单的单词a.l和b.l中,指向同一列表对象。
一个非常相似的讨论——"最小惊讶"和可变的默认参数