Python-属性拦截器——__getattribute__

__getattribute__(self, item):

当一个类的属性被实例访问时,会自动调用该方法。
当实例调用属性时,比如s1.name,会把name作为实参传进__getattribute__方法中,经过一系列操作后,再把name处理后的结果返回。Python中只要定义了继承object的类,就默认存在属性拦截器,只不过是拦截后没有进行任何操作,而是直接返回。
所以我们可以自己改写__getattribute__方法来实现相关功能,比如查看权限、打印log日志等;如果重写了__getattribute__,则类会调用重写的方法,所以这个方法必须要有renturn返回值,返回传进去的属性,否则调用属性会出现失败的情况。

class ClassA:
    x = 'a'

    def __init__(self):
        self.y = 'b'

    def __getattribute__(self, item):
        return '__getattribute__'


a = ClassA()
# 使用实例直接访问存在的类属性时,会调用__getattribute__方法
print(a.x)

# 使用实例直接访问实例存在的实例属性时,会调用__getattribute__方法
print(a.y)

# 使用实例直接访问实例不存在的实例属性时,也会调用__getattribute__方法
print(a.z)
>>>
 __getattribute__
 __getattribute__
 __getattribute__

与__getattribute__功能接近的,还有:

__getattr__(self, key):

重载__getattr__方法对类及其实例未定义的属性有效。也就是说,如果访问的属性存在,就不会调用__getattr__方法。这个属性的存在,包括类属性和实例属性。

class ClassA:

    def __getattr__(self, item):
        print('__getattr__')


a = ClassA()
a.x
>>>
__getattr__

当同时定义__getattribute__和__getattr__时,__getattr__方法不会再被调用,除非显示调用__getattr__方法或引发AttributeError异常。

class ClassA:

    def __getattr__(self, item):
        print('__getattr__')

    def __getattribute__(self, item):
        print('__getatttribute__')


a = ClassA()
a.x
>>>
__getatttribute__

__setattr__(self, key, value):

当试图给对象的key属性赋值的时候将会被调用,若属性不存在,先创建再赋值。

你可能感兴趣的:(Python-属性拦截器——__getattribute__)