属性查找顺序

一般情况下属性访问的默认行为是从对象的字典中获取的;
例如testinstance.name 的查找链为:


testinstance.dict[‘name’] —-> type(testisntance).dict[‘name’] —->** **type(testinstance)


get

一个类中定义了get()、set()、delete()中的任何方法,则这个类的对象称为描述符,更多关于描述符的知识详见python描述符

  1. class M:
  2. def __init__(self, x=1):
  3. self.x = x
  4. def __get__(self, instance, owner):
  5. print("调用__get__方法")
  6. return self.x
  7. def __set__(self, instance, value):
  8. print("调用__set__方法")
  9. self.x = value
  10. class AA:
  11. m = M(x=2)
  12. if __name__ == '__main__':
  13. a = AA()
  14. print(a.m)
  15. print('*'*30)
  16. a.m = 33
  17. print(a.m)
  18. ------------ ------------
  19. #调用__get__方法
  20. #2
  21. #******************************
  22. #调用__set__方法
  23. 调用__get__方法
  24. #33

getattr

一般只在当对象的属性不存在的时候调用,如果正常的可以找到对象属性的话,是不会调用getattr方法的

  1. class B:
  2. a = 1
  3. def __getattr__(self, item):
  4. print("调用__getattr__方法")
  5. return item
  6. if __name__ == '__main__':
  7. b = B()
  8. print(b.a) # 1
  9. print(b.aa) # 调用__getattr__方法
  10. # aa


getattribute

不管属性存不存在,该方法都会被调用,当类中同时存在getattributegetattr时,getattr将不会被调用,假如我们想保留getattr方法的作用,可在getarrtibute方法中返回父类的同名方法

  1. class B:
  2. a = 1
  3. def __getattribute__(self, item):
  4. print("调用__getattribute__方法")
  5. return item
  6. # 返回父类的同名方法,可保留__getattr__方法的作用
  7. # return object.__getattribute__(self, item
  8. def __getattr__(self, item):
  9. print("调用__getattr__方法")
  10. return item
  11. if __name__ == '__main__':
  12. b = B()
  13. print(b.a)
  14. print(b.aa)
  15. -----------------
  16. #调用__getattribute__方法
  17. #a
  18. #调用__getattribute__方法
  19. #aa

getattr()

内置函数,可用来获取对象的属性和方法

  1. class B:
  2. a = 1
  3. def __getattribute__(self, item):
  4. print("调用__getattribute__方法")
  5. return object.__getattribute__(self, item)
  6. def __getattr__(self, item):
  7. print("调用__getattr__方法")
  8. return item
  9. def bb(self):
  10. return "实例方法"
  11. if __name__ == '__main__':
  12. b = B()
  13. print(getattr(b, 'a')) # 相当于 b.a
  14. print(getattr(b, 'bb')()) # 相当于b.bb
  15. print(getattr(B, 'a')) # 相当于B.a
  16. ----------------
  17. #调用__getattribute__方法
  18. #1
  19. #调用__getattribute__方法
  20. #实例方法
  21. #1

getitem

大致作用同getattribute方法,主要区别在于getitem让类实例可以通过[]获取

  1. class B:
  2. a = 1
  3. def __getattribute__(self, item):
  4. print("调用__getattribute__方法")
  5. return object.__getattribute__(self, item)
  6. def __getattr__(self, item):
  7. print("调用__getattr__方法")
  8. return item
  9. def __getitem__(self, item):
  10. print("调用__getitem__")
  11. return object.__getattribute__(self, item)
  12. def bb(self):
  13. return "实例方法"
  14. if __name__ == '__main__':
  15. b = B()
  16. print(b['a']) #1