从扩展类更新dict属性更新基类。为什么?

时间:2012-03-06 08:57:09

标签: python class dictionary extends

>>> class Test(object):
...   test = {}
... 
>>> class Test2(Test):
...   pass
... 
>>> Test2.test.update({1:2})
>>> Test.test
{1: 2}
>>> 

我期待{}。也适用于旧式的课程。

5 个答案:

答案 0 :(得分:2)

您需要使用2个下划线来激活类/属性munging

>>> class Test(object):
...     __test = {}
...
>>> class Test2(Test):
...     pass
...
>>> Test2.__test.update({1:2})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Test2' has no attribute '__test'

由于属性重新设置,可以在Test2._Test__test

找到该属性

如果您希望所有子类自动获取自己的__test属性,则可以使用Test的元类

答案 1 :(得分:1)

update的工作原理并不奇怪。关键是testclass attribute,类属性在类之间共享,(直到有人将test重新绑定到其他东西)。

看看这个IDE会话:

>>> class Test(object):
...     test = {}
... 
>>> class Test2(Test):
...     pass
... 
>>> id(Test.test)
32424144
>>> id(Test2.test)
32424144
>>> Test.test.update({1:2})
>>> Test2.test
{1: 2}
>>> Test2.test = {}
>>> id(Test2.test)
32424480
>>> Test.test
{1: 2}
>>> Test2.test
{}
>>> del Test2.test
>>> Test2.test
{1: 2}

有关类属性如何工作的更多信息,请查看“类”下的Data Model Reference

答案 2 :(得分:0)

Test2.test.update({1:2})

这将更新您的基类Test属性,该属性由Test2继承。

如果你想让他们每个人都拥有自己的词典,请执行:

>>> class Test(object):
...     test = {}
... 
>>> class Test2(Test):
...     test = {}
... 
>>> Test2.test.update({1:2})
>>> Test.test
{}
>>> 

Python有一个我非常喜欢的功能:数据继承,你刚刚看到它。

答案 3 :(得分:0)

这是一个参考问题。举个例子:

>>> class Test(object):
...   val = 1
... 
>>> class Test2(Test):
...   pass
... 
>>> Test2.val = 2
>>> Test.val
1

这里为子类val重新赋值为2.

对于列表和词典,两者都引用相同的对象,任何更新/追加都将在超类中可见。如果你重新签名:

>>> class Test(object):
...   test = {}
... 
>>> class Test2(Test):
...   pass
... 
>>> Test2.test = {1:2}
>>> Test.test
{}

答案 4 :(得分:0)

因为它们是同一个对象。更准确地说,Test2.test是一种访问Test.test所做同样事情的方式,因为当它在本地找不到时,会在超类中查找。

我不明白为什么你会有所不同。 (它不会像你想象的那样以我能想到的任何其他语言的方式工作。)