2017-06-09 60 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 
相关问题