Python:类属性与实例属性

在了解类的属性之前,应该先对__dict__属性有所了解。官方文档是这样说的

A dictionary or other mapping object used to store an object’s (writable) attributes.

中文意思是:__dict__是一个储存类的可写属性的的字典或者其他映射对象。

实际上大部分情况下都是一个字典。所以下文默认以字典来使用__dict__

类属性&实例属性


  • 类属性在类被申明时便确定好了,类似于这样
class Test:
    name = "Hell"

name就是类属性,我们可以直接通过类的__dict__里拿到这个值。也可以直接使用Test.name来调用。

Test.__dict__["name"]
  • 实例属性在__init__()运行之后才被确定
class Test:
    name = "Hell"
    def __init__(self, user):
        self.user = user

Fuck = Test("fuck")

这里面的self.user就是实例属性,可以通过Fuck.user来调用,也能用Fuck.__dict__["user"]来调用。

  • 类属性和实例属性的冲突
class Test:
    name = "Hell"
    def __init__(self, user):
        self.name = user

Fuck = Test("fuck")

这段代码运行后,当我们使用Fuck.name调用属性的时候,会发现值是fuck
此时,实例属性盖住了类属性。使我们不能直接使用self.name调用类属性。

  1. 可以使用Fuck.__class__.__dict__["name"]来访问类属性。
  2. 或者删掉重名的实例属性del Fuck.name
    之后,再调用Fuck.name这时我们就能调用到类属性了。
    然而,此时会发现Fuck.__dict__["name"]会报错,提醒你没有这个key。
    这很好理解,Fuck.__dict__这个字典存储的是Fuck这个实例的属性,而不是Test这个类的。

事实上,getattr(Fuck, "name")等价于Fuck.name,它们查找顺序是这样的

  1. 实例属性
    如果没查到,继续向下查
  2. 类属性
    如果还没查到,报错

setattrdelattrhasattr都是类似的。优先查找/修改实例属性,然后是类属性。


Fuck.__class__.__dict__["name"]等价于Test.__dict__["name"]等价于Test.name
原因如上

你可能感兴趣的:(Python:类属性与实例属性)