Python - __getattr__和__getattribute__的区别

时间:2023-03-10 00:22:54
Python - __getattr__和__getattribute__的区别

传送门

  1. https://docs.python.org/3/reference/datamodel.html#object.__getattr__
  2. https://docs.python.org/3/reference/datamodel.html#object.__getattribute__
  3. https://*.com/questions/4295678/understanding-the-difference-between-getattr-and-getattribute
  4. https://*.com/questions/3278077/difference-between-getattr-vs-getattribute

区别

  1. 当正常访问属性失败,即f.x,x不存在,会触发__getattr__
  2. 无论有无f.x,都会触发__getattibute__

Talk is cheap

__getattr__单个出现

class Foo:

    def __init__(self, x):
self.x = x def __getattr__(self, item):
#return self.__dict__[item]
return '__getattr__' f1 = Foo(1)
print(f1.x)
print(f1.xxxxxx) #访问不存在的属性访问,触发__getattr__

Python - __getattr__和__getattribute__的区别

__getattribute__单个出现

class Foo:

    def __init__(self, x):
self.x = x def __getattribute__(self, item):
return '__getattribute__' f1 = Foo(1)
print(f1.x) # 访问存在的属性,也会直接执行__getattribute__
print(f1.xxx) # 访问不存在的属性,也会直接执行__getattribute__

Python - __getattr__和__getattribute__的区别

__getattr__和__getattibute__同时存在

class Foo:

    def __init__(self, x):
self.x = x def __getattr__(self, item):
return '执行的是我,__getattr__'
# return self.__dict__[item] def __getattribute__(self, item):
print('不管属性是否存在,我都执行,__getattribute__')
raise AttributeError('__getattribute__的AttributeError') f1 = Foo(1)
# 当两者同时存在的时候,只会执行__getattribute__;如果在__getattribute__过程中抛出AttributeError,那么就执行__geattr__
print(f1.x)
# print(f1.xx)

Python - __getattr__和__getattribute__的区别

18+ Warning

最好不要使用__getattribute__,不然有可能导致无限递归的可能。