属性查找顺序
一般情况下属性访问的默认行为是从对象的字典中获取的;
例如testinstance.name 的查找链为:
testinstance.dict[‘name’] —-> type(testisntance).dict[‘name’] —->** **type(testinstance)
get
一个类中定义了get()、set()、delete()中的任何方法,则这个类的对象称为描述符,更多关于描述符的知识详见python描述符
class M:
def __init__(self, x=1):
self.x = x
def __get__(self, instance, owner):
print("调用__get__方法")
return self.x
def __set__(self, instance, value):
print("调用__set__方法")
self.x = value
class AA:
m = M(x=2)
if __name__ == '__main__':
a = AA()
print(a.m)
print('*'*30)
a.m = 33
print(a.m)
------------ ------------
#调用__get__方法
#2
#******************************
#调用__set__方法
调用__get__方法
#33
getattr
一般只在当对象的属性不存在的时候调用,如果正常的可以找到对象属性的话,是不会调用getattr方法的
class B:
a = 1
def __getattr__(self, item):
print("调用__getattr__方法")
return item
if __name__ == '__main__':
b = B()
print(b.a) # 1
print(b.aa) # 调用__getattr__方法
# aa
getattribute
不管属性存不存在,该方法都会被调用,当类中同时存在getattribute和 getattr时,getattr将不会被调用,假如我们想保留getattr方法的作用,可在getarrtibute方法中返回父类的同名方法
class B:
a = 1
def __getattribute__(self, item):
print("调用__getattribute__方法")
return item
# 返回父类的同名方法,可保留__getattr__方法的作用
# return object.__getattribute__(self, item
def __getattr__(self, item):
print("调用__getattr__方法")
return item
if __name__ == '__main__':
b = B()
print(b.a)
print(b.aa)
-----------------
#调用__getattribute__方法
#a
#调用__getattribute__方法
#aa
getattr()
内置函数,可用来获取对象的属性和方法
class B:
a = 1
def __getattribute__(self, item):
print("调用__getattribute__方法")
return object.__getattribute__(self, item)
def __getattr__(self, item):
print("调用__getattr__方法")
return item
def bb(self):
return "实例方法"
if __name__ == '__main__':
b = B()
print(getattr(b, 'a')) # 相当于 b.a
print(getattr(b, 'bb')()) # 相当于b.bb
print(getattr(B, 'a')) # 相当于B.a
----------------
#调用__getattribute__方法
#1
#调用__getattribute__方法
#实例方法
#1
getitem
大致作用同getattribute方法,主要区别在于getitem让类实例可以通过[]获取
class B:
a = 1
def __getattribute__(self, item):
print("调用__getattribute__方法")
return object.__getattribute__(self, item)
def __getattr__(self, item):
print("调用__getattr__方法")
return item
def __getitem__(self, item):
print("调用__getitem__")
return object.__getattribute__(self, item)
def bb(self):
return "实例方法"
if __name__ == '__main__':
b = B()
print(b['a']) #1