2010-10-12 59 views
3

這是一個完全理論上的問題。假設下面的代碼:對象與類變量

>>> class C: 
...  a = 10 
...  def f(self): self.a = 999 
... 
>>> 
>>> C.a 
10 
>>> c = C() 
>>> c.a 
10 
>>> c.f() 
>>> c.a 
999 

在這一點上,是類變量C.a通過對象c仍然可以訪問?

+1

你試過了,它工作。這不是理論上的。這甚至不是一個真正的問題。有效。你還想知道什麼? – 2010-10-12 21:32:49

+0

我想知道什麼? 「在這一點上,類變量C.a仍然可以通過對象c訪問嗎?」 – 2010-10-13 04:40:31

回答

4

是的,雖然c.__class__.atype(c).a。這兩者在舊式課程中稍有不同(希望那些現在都已經死了 - 但你永遠不知道......)有type()<type 'instance'>(和__class__按預期工作),而對於新式課程,type()是相同的到__class__除非對象覆蓋屬性訪問權限。

1

所有類變量都可以通過從該類實例化的對象訪問。

>>> class C: 
...  a = 10 
...  def f(self): self.a = 999 
... 
>>> C.a 
10 
>>> c = C() 
>>> c.a 
10 
>>> c.f() 
>>> c.a 
999 
>>> c.__class__.a 
10 
>>> c.a 
999 
>>> del(c.a) 
>>> c.a 
10 

屬性首先在對象命名空間中搜索,然後在類中搜索。

1

是的,您可以從對象c,àla c.a訪問a。該值最初將10

但是,如果調用c.f()c.a值現在是999,C.a仍將10.同樣的,如果你現在更改C.a,比方說,1000,c.a仍然是999

基本上,當實例的C一個實例,它將使用類變量作爲自己的a值,直到您更改該實例的a的價值,在這種情況下,將不再「分享」a同班同學。

1

在類實例上分配給它之後,同時存在名爲a的類屬性和名爲a的實例屬性。我說明:

>>> class Foo(object): 
...  a = 10 
... 
>>> c = Foo() 
>>> c.a 
10 
>>> c.a = 100 # this doesn't have to be done in a method 
>>> c.a # a is now an instance attribute 
100 
>>> Foo.a # that is shadowing the class attribute 
10 
>>> del c.a # get rid of the instance attribute 
>>> c.a  # and you can see the class attribute again 
10 
>>> 

不同的是,存在一個在Foo.__dict__一個條目,而另一個存在如在c.__dict__一個條目。當您訪問instance.attribute時,如果它存在,則返回instance.__dict__['attribute'],如果不存在,則檢查type(instance).__dict__['attribute']。然後檢查該類的超類,但稍微複雜一些。

但無論如何,主要的一點是它不一定是一個或另一個。一個類和一個實例可以具有不同的具有相同名稱的屬性,因爲它們存儲在兩個單獨的字典中。

+0

這是這裏最清楚的解釋。謝謝你的回答。 – 2010-10-12 21:36:18