Python:类属性与实例属性
2018-01-30 本文已影响153人
子休_
在了解类的属性之前,应该先对__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
调用类属性。
- 可以使用
Fuck.__class__.__dict__["name"]
来访问类属性。 - 或者删掉重名的实例属性
del Fuck.name
之后,再调用Fuck.name
这时我们就能调用到类属性了。
然而,此时会发现Fuck.__dict__["name"]
会报错,提醒你没有这个key。
这很好理解,Fuck.__dict__
这个字典存储的是Fuck
这个实例的属性,而不是Test
这个类的。
事实上,getattr(Fuck, "name")
等价于Fuck.name
,它们查找顺序是这样的
- 实例属性
如果没查到,继续向下查 - 类属性
如果还没查到,报错
setattr
,delattr
和hasattr
都是类似的。优先查找/修改实例属性,然后是类属性。
Fuck.__class__.__dict__["name"]
等价于Test.__dict__["name"]
等价于Test.name
原因如上