点拦截方法
目录
面向对象中的魔法方法
在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为属性名。当getattribute与getattr同时存在,只会执行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__执行了