点拦截方法

面向对象中的魔法方法

在Python中以双下划线开头和结尾的方法都是魔法方法,在某种情况下回触发它们的执行,比如__init__方法会在类名()实例化对象时执行内部代码。魔法方法都经过处理,不遵循属性隐藏原则,可以在类外部直接通过对象.属性的方式执行。


点拦截方法

__setattr__(self, key, value)

在为对象赋值对象.属性 = 值 时会触发它的执行,无论属性是否存在。需要注意的是,在使用__init__初始化赋值或者其他方法内出现self.属性 = 值时,也会触发__setattr__的执行。key为属性名,value为属性值。

class Foo:
    def __init__(self,x):
        self.x = x

    def __setattr__(self, key, value):
        print(key,value)
        print('__setattr__执行了')
        # self.key = value  这样会无限递归
        # self.__dict__[key] = value  应该使用这个

f = Foo(1)

x 1
__setattr__执行了

__getattr__(self, item)

在或取对象属性时对象.属性时,如果属性不存在,才会触发它的执行,item为属性名。

__delattr__(self, item)

在删除属性del 对象.属性时,会触发它的执行,无论属性是否存在,item为属性名。

class Func:
    a = 10
    def __setattr__(self, key, value):
        print('__setattr__执行了')

    def __getattr__(self, item):
        print('__getattr__执行了,说明获取的属性不存在!')

    def __delattr__(self, item):
        print('__delattr__执行了')
        # del self.item 这样会无限递归
        # self.__dict__.pop(item)  应该使用这个

f1 = Func()

f1.a = 10  # __setattr__执行了
f1.b       # __getattr__执行了,说明获取的属性不存在!
f1.a       # 属性存在getattr则不会执行
del f1.a   # __delattr__执行了
del f1.b   # __delattr__执行了

__getattribute__(self, item)

在或取对象属性时对象.属性时,无论属性是否存在,都会触发它的执行,item为属性名。当getattributegetattr同时存在,只会执行getattrbute,除非getattribute在执行过程中抛出异常AttributeError。item为属性名。

class Func:
    def __getattr__(self, item):
        print(item)
        print('__getattr__执行了,说明获取的属性不存在!')

    def __getattribute__(self, item):
        print(item)
        print('__getattribute__执行了')

f = Func()
f.a
a
__getattribute__执行了

原文地址:https://www.cnblogs.com/ChiRou/p/14209996.html