2012-03-06 81 views
1
>>> class Test(object): 
... test = {} 
... 
>>> class Test2(Test): 
... pass 
... 
>>> Test2.test.update({1:2}) 
>>> Test.test 
{1: 2} 
>>> 

我在期待{}。也適用於舊式課程。從擴展類更新字典attrib更新基類。爲什麼?

+0

小心explin爲什麼要解釋什麼不同? 「test」類屬性的Test2實例從哪裏來?純粹的魔法? – jsbueno 2012-03-06 19:05:42

回答

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

您需要使用2個下劃線來激活類/屬性,因爲改寫(munging)的屬性的屬性的改寫(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

+0

糟糕。抱歉。我並不是真的想隱藏這個屬性。 – MarkSteve 2012-03-06 09:03:04

+0

設置屬性本身不會更新基類。詞典的更新方法有些奇怪。 – MarkSteve 2012-03-06 09:08:45

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

這會更新您的基類Test屬性,該屬性由Test2繼承。

如果你想希望他們每個人都有自己的字典,這樣做:

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

Python有一個功能,我非常喜歡:數據繼承,您剛纔已經在行動見過。

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 
{} 
0

因爲它們是同一個對象。更準確地說,Test2.test是一種訪問Test.test所做的同樣事情的方法,因爲當它在本地找不到時,它會在超類中查找。

我不明白你爲什麼期望有任何不同。 (它的行事方式與我所能想到的任何其他語言不同。)