目录
当属性查找没有找到的时候(报错AttriErro)时,会触发此方法
定义魔术方法来自定义类实例的属性访问。
总结:当父类的方法不能满足自己的功能需求时,可以重写父类方法,重写时把想要增加的功能添加上后,通过super().父类方法()来扩展父类方法的功能,这样,自己重写的方法,既有了父类方法的功能,又有了自己添加的功能。
1.object.__getattr__
当属性查找没有找到的时候(报错AttriErro)时,会触发此方法
class Attr:
def __getattr__(self, item):
# 当访问对象属性的时候,如果该属性不存在,并且报错AttrError时,此方法被触发。
print('---getattr---方法触发了')
return 666
if __name__ == '__main__':
a = Attr()
print(a.name)
# 输出:
# ---getattr - --方法触发了
# 666
2.object.__getattribute__
当查找属性时,第一时间会调用此方法
class Attr:
def __getattr__(self, item):
# 当访问对象属性的时候,如果该属性不存在,并且报错AttrError时,此方法被触发。
print('---getattr---方法触发了')
# 触发时调用父类的getattribute方法,查找属性,如果没找到,抛出 AttributeError: 'Attr' object has no attribute 'name'
object.__getattribute__(self, item)
def __getattribute__(self, item):
# 访问属性时,会第一时间触发此方法查找属性
print('---getattribute---方法触发了')
# 增加自定义功能
print('此处增加了自定义功能')
# 增加了自定义功能后,调用父类的getattribute方法查找属性
return super().__getattribute__(item)
if __name__ == '__main__':
a = Attr()
a.name = '春田'
print(a.name)
# 输出:
---getattribute - --方法触发了
此处增加了自定义功能
春田
3.object.__setattr__
设置属性时,会触发此方法设置属性
class Attr:
def __setattr__(self, key, value):
# 在给对象设置属性的时候,会触发此方法
print('---setattr---方法触发了')
print(key)
print(value)
if __name__ == '__main__':
a = Attr()
a.name = '春田'
# 输出:
---setattr - --方法触发了
name
春田
class Attr:
def __setattr__(self, key, value):
# 在给对象设置属性的时候,会触发此方法
print('---setattr---方法触发了')
if key == 'name':
# 锁死对象的name属性,无法被对象外部修改,不管外部a.name设置为多少,name属性始终不会被修改
super().__setattr__(key, "羊咩咩")
else:
# 设置的对象属性不是name,就可正常修改
super().__setattr__(key, value)
if __name__ == '__main__':
a = Attr()
a.name = '春田'
print(a.name)
a.age = 130
print(a.age)
# 输出:
---setattr - --方法触发了
羊咩咩
---setattr - --方法触发了
130
4.object.__delattr__
在del 对象属性时,会触发此方法
class Attr:
def __delattr__(self, item):
# 删除属性的时候会触发此方法
print('---delattr---方法触发了')
if __name__ == '__main__':
a = Attr()
a.name = '春田'
del a.name
# 输出:
---delattr - --方法触发了
class Attr:
def __delattr__(self, item):
# 删除属性的时候会触发此方法
print('---delattr---方法触发了')
# 扩展功能
print('此处是扩展的功能')
# 调用父类的delattr方法删除属性
super().__delattr__(item)
print(f'属性{item}已经被删除了')
if __name__ == '__main__':
a = Attr()
a.name = '春田'
del a.name
print(a.name)
# 输出:
---delattr - --方法触发了
此处是扩展的功能
属性name已经被删除了
AttributeError: 'Attr' object has no attribute 'name'
class Attr:
def __delattr__(self, item):
# 删除属性的时候会触发此方法
print('---delattr---方法触发了')
# 扩展功能,如果想删除的属性是name,就拒绝,不能删除
if item == 'name':
print(f'{item}属性不允许删除') # 保护name属性不会被删除
else:
# 调用父类的delattr方法删除属性
super().__delattr__(item)
print(f'属性{item}已经被删除了')
if __name__ == '__main__':
a = Attr()
a.name = '春田'
del a.name
print(a.name)
# 输出:
---delattr - --方法触发了
name属性不允许删除
春田