你所看到的行爲正是你應該期待的。當你定義一個類
>>> class Foo(object): pass
...
可以修改是類 - 而不是它的實例,類本身 - 因爲類是另一個對象,存儲在變量foo中。所以,舉例來說,你可以獲取和設置類的屬性:
>>> Foo.a = 1
>>> Foo.a
1
換句話說,在class
關鍵字創建一個新類型的對象和綁定指定名稱到該對象。現在
,如果你定義一個類裏面另一個類(這是做的,順便說一個奇怪的事情),即相當於定義的類體中的局部變量。而且你知道在一個類的內部定義局部變量是什麼:它將它們設置爲類屬性。換句話說,本地定義的變量存儲在類對象中,而不是存儲在單個實例中。因此,
>>> class Foo(object):
... class Bar(object): pass
...
定義了一類Foo
與一種類屬性,Bar
,這恰好本身是一類。儘管如此,這裏沒有任何子類化 - 類別Foo
和Bar
是完全獨立的。(你已經實現可複製的行爲如下:
>>> class Foo(object):
... class Bar(object): pass
...
>>> class Foo(object): pass
...
>>> class Bar(object): pass
...
>>> Foo.Bar = Bar
。)
所以你總是修改同一個變量!當然,你會改變你看到的價值;你已經改變了他們自己!
你的問題似乎是你在實例和類屬性之間有些混淆,它們根本不是一回事。
A 類屬性是一個定義在整個類別上的變量。也就是說,該類的任何實例都將共享相同的變量。例如,大多數方法都是類屬性,因爲您希望在每個實例(通常)上調用相同的方法。您還可以使用類屬性來處理全局計數器(您已實例化此類的次數?)以及應該在實例之間共享的其他屬性。
一個實例屬性是一個類的實例特有的變量。也就是說,每個實例都有一個不同的變量副本,可能有不同的內容。這是您將數據存儲在類中的位置 - 如果您有Page
類,那麼您希望contents
屬性按每個實例存儲,因爲不同的Page
s當然需要不同的contents
。
在你的例子中,你想要Child1.Subcls.a
和Child2.Subcls.a
爲不同的變量。自然,那麼,他們應該依賴於實例!
這可能有點信仰的飛躍,但是你想在Python中實現Java風格的接口?換句話說,你是否試圖指定類所具有的屬性和方法,而不實際定義這些屬性?
這被認爲是非pythonic的事情,因爲普遍的共識是你應該允許類做任何他們想做的事,並且捕獲當它們沒有定義需要的屬性時產生的異常或方法。然而,最近人們已經意識到接口實際上有時是一件好事,並且新的功能被添加到Python以允許:abstract base classes。
你正在處理類,而不是類的實例。那是你要的嗎? – robert
「我期望避免創建實例,因爲我稍後使用該功能。」嚴重的錯誤觀念。請找一個關於面向對象設計的更好的教程。 –