2017-06-09 97 views
5

我有一個類Foo與類變量remote。我可以使用self.remote訪問類變量remote嗎?我可以使用self訪問類變量嗎?

class Foo: 
    remote = False 

    def __init__(self): 
     self.remote = True 

    @classmethod 
    def print_remote(cls): 
     print(cls.remote) #prints False but why? 
+1

你有'remote'的* class level *和* instance level * - 你想要做什麼? –

+0

我想知道self.remote和cls.remote是相同的變量還是不同的。 – 2ank3th

回答

7

分配在__init__remoteself意味着instance.remote發現首先,當你通過self訪問(當然沒有描述周圍)。爲了得到這兩個選項,訪問無論是從selftype(self),也就是說,無論是從實例或類:

def print_remote(self): 
    print(type(self).remote) # class remote 
    print(self.remote)  # instance remote 

type(self).remote基本上等同於self.__class__.remote,但在一般情況下,你應該避免抓dunder名( (type在這種情況下)

這些生活在不同的字典,是不同的變量。 self.remote生活在實例字典中,而class.remote在類字典中。

>>> Foo().__dict__['remote'] 
True 
>>> Foo.__dict__['remote'] 
False 

當您通過clsclassmethod訪問(或type(self)在正常的方法),你會得到一個類,當您通過self訪問你的實例之一。

+1

很高興能夠訪問'remote'變量,但我不喜歡兩個不同事物具有相同名稱的事實。關於實例成員廣泛使用的'm_'表示法,我喜歡用'c_'前綴我的類變量。這可以消除諸如'self.remote'這樣的調用,它可以變爲'self.c_remote'或'self.m_remote'。 –

+0

很好的解釋謝謝。 – 2ank3th

+0

另請注意,'self .__ class __。remote'相當於'type(self).remote'。 –

1

是的,你可以自己訪問類變量。但是,如果你有一個實例變量,當你使用self時,你將訪問實例變量,因爲它隱藏了類變量。

3
In [1]: class Foo: 
    ...:  x = 0 
    ...: 

In [2]: f = Foo() 

In [4]: f.__dict__ # empty 
Out[4]: {} 

In [5]: Foo.__dict__ # have the variable x = 0 
Out[5]: 
mappingproxy({'__dict__': <attribute '__dict__' of 'Foo' objects>, 
       '__doc__': None, 
       '__module__': '__main__', 
       '__weakref__': <attribute '__weakref__' of 'Foo' objects>, 
       'x': 0}) 

當您嘗試在一個對象訪問一個變量,Python會首先查找對象,如果它不存在,然後它會在類字典。

In [6]: Foo.x = 10 # changing class variable 

In [7]: f.__dict__ # still empty. 
Out[7]: {} 

In [8]: f.x # gives you Foo's x as object doesn't have that item. 
Out[8]: 10 

In [9]: f.x = 20 # this line creates a new variable in x. Now both class and object has their own variable x 

In [10]: f.__dict__ # f has its own x. 
Out[10]: {'x': 20} 

In [11]: Foo.__dict__ # Foo has its own x. 
Out[11]: 
mappingproxy({'__dict__': <attribute '__dict__' of 'Foo' objects>, 
       ... 
       'x': 10}) 
In [12]: f.x # always you will get the value from f.__dict__ 
Out[12]: 20 
In [16]: f.x = 50 # changing the value of object's variable 

In [17]: Foo.x # above statement didn't affect class's variable. 
Out[17]: 10 

In [13]: del f.x # delete object's x 

In [14]: f.x # now f doesn't have x, you get the value from class Foo. 
Out[14]: 10 
相關問題