我可以使用 self 访问类变量吗?



我有一个类Fooremote类变量。我可以使用self.remote访问类变量remote吗?

class Foo:
   remote = False
   def __init__(self):
       self.remote = True 
   @classmethod
   def print_remote(cls):
       print(cls.remote) #prints False but why? 

remote分配给__init__中的self意味着当您通过self访问instance.remote时,首先找到它(前提是周围没有描述符(。要获取这两个选项,请从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

当您使用classmethod(或以普通方法type(self)(通过cls访问时,您将获得类 1,当您通过 self 访问时,您将获得实例一。

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

是的,您可以使用 self 访问类变量。但是,如果你有一个实例变量,当你使用 self 时,你将访问实例变量,因为它正在隐藏类变量。

最新更新