【发布时间】:2011-08-11 02:30:20
【问题描述】:
我有一棵有数十万个节点的大树,我正在使用__slots__ 来减少内存消耗。我刚刚发现了一个非常奇怪的错误并修复了它,但我不明白我看到的行为。
这是一个简化的代码示例:
class NodeBase(object):
__slots__ = ["name"]
def __init__(self, name):
self.name = name
class NodeTypeA(NodeBase):
name = "Brian"
__slots__ = ["foo"]
然后我执行以下操作:
>>> node = NodeTypeA("Monty")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __init__
AttributeError: 'NodeTypeA' object attribute 'name' is read-only
如果未定义NodeTypeA.name,则没有错误(旁注:该属性是错误的,并且没有理由存在)。如果从未定义过NodeTypeA.__slots__,也没有错误,因此它有一个__dict__。
我不明白的是:为什么超类中存在类变量会干扰在子类的插槽中设置实例变量?
谁能解释为什么这种组合会导致object attribute is read-only 错误?我知道我的示例是人为的,在实际程序中不太可能是故意的,但这并没有使这种行为变得不那么奇怪。
谢谢,
乔纳森
【问题讨论】:
-
NodeTypeA正在创建一个类变量name,而不是为NodeBase中定义的实例变量赋值。这是故意的吗? -
一开始并不是故意的——我不小心在我的代码中出现了这个问题,导致了我所询问的错误。但是后来我很好奇为什么代码会这样,所以我故意把它放在我的代码示例中。