文章目录
1、__getattr__
- 调用不存在的属性时,会调用此函数
class Animal:
a=1
def __init__(self,name):
self.name=name
def __getattr__(self, item):
print("你找的【%s】属性不存在"%item)
if __name__ == '__main__':
animal=Animal("佩奇")
animal.aaa #调用不存在的属性才会执行__getattr__
输出:
你找的【aaa】属性不存在
2、__delattr__
2.1、__delattr__
的触发
- 执行删除操作时会触发此函数
class Animal:
a=1
def __init__(self,name):
self.name=name
def __delattr__(self, item):
print("删除操作__delattr__")
#del self.item #无限递归
self.__dict__.pop(item)
if __name__ == '__main__':
animal=Animal("佩奇")
del animal.a
2.2、__delattr__
的作用
- 系统有个默认的
__delattr__
- 如果类中定义了
__delattr__
主法,系统默认的将失效 __delattr__
方法被重写,需要自己写设置属性的方法,如果不写,值将无法删除。- 可以用
self.__dict__.pop(item)
- 不能用
del self.item
,否则会无限递归
class Animal:
name = "待初始化"
def __init__(self, name):
self.name = name
def __delattr__(self, item):
pass
if __name__ == '__main__':
animal = Animal("佩奇")
print(animal.__dict__)
print(animal.name)
del animal.name
print(animal.__dict__)
print(animal.name)
2.3、__delattr__
的用法示例
不允许删除任何属性
class Animal:
name = "待初始化"
def __init__(self, name):
self.name = name
def __delattr__(self, item):
print("【%s】属性不允许删除"%item)
if __name__ == '__main__':
animal = Animal("佩奇")
print(animal.__dict__)
print(animal.name)
del animal.name
print(animal.__dict__)
print(animal.name)
输出:
{‘name’: ‘佩奇’}
佩奇
【name】属性不允许删除
{‘name’: ‘佩奇’}
佩奇
3、__setattr__
3.1、__setattr__
的触发
- 为类的属性赋值时会触发
class Animal:
a = 1
def __init__(self, name):
self.name = name
def __setattr__(self, key, value):
print("执行__setattr__")
#self.key=value #这样写会无限递归
self.__dict__[key]=value
if __name__ == '__main__':
animal = Animal("佩奇")
print(animal.__dict__)
animal.a=2
print(animal.__dict__)
3.2、__setattr__
的作用
-
系统有个默认的
__setattr__
-
如果类中定义了
__setattr__
主法,系统默认的将失效 -
__setattr__
方法被重写,需要自己写设置属性的方法,如果不写,值将无法传入,本例中“佩奇”就无法传给name。 -
可以用
self.__dict__[key]=value
-
不能用
self.key=value
,否则会无限递归
class Animal:
name="待初始化"
def __init__(self, name):
self.name = name
def __setattr__(self, key, value):
print("执行__setattr__")
#self.key=value
#self.__dict__[key]=value
if __name__ == '__main__':
animal = Animal("佩奇")
print(animal.__dict__)
print(animal.name)
输出:
执行__setattr__
{}
待初始化
3.2、__setattr__
用法示例
实例化Animal时name只能传字符串
class Animal:
name = "待初始化"
def __init__(self, name):
self.name = name
def __setattr__(self, key, value):
if (key=="name" and type(value) is str):
self.__dict__[key]=value
else:
print("【%s】不是字符串,无法赋值给【%s】"%(value,key))
if __name__ == '__main__':
animal = Animal("佩奇")
print(animal.__dict__)
print(animal.name)
animal = Animal(1)
print(animal.__dict__)
print(animal.name)
输出:
{‘name’: ‘佩奇’}
佩奇
【1】不是字符串,无法赋值给【name】
{}
待初始化
4、__getattribute__
4.1、__getattribute__
触发的条件
- 实例对象调用存在的属性会触发
- 实例对象调用不存在的属性会触发
__getattr__
就没有了触发的机会
class Animal:
def __init__(self,name):
self.name=name
def __getattr__(self, item):
print("执行了__getattr__")
def __getattribute__(self, item):
print("执行了___getattribute__")
if __name__ == '__main__':
animal=Animal("佩奇")
animal.name #属性存在
animal.aaaa #属性不存在
输出:
执行了___getattribute__
执行了___getattribute__
4.2、AttributeError异常时会继续调用__getattr__
__getattribute__
抛出AttributeError异常时,会继续调用__getattr__
- 其他异常不会
class Animal:
def __init__(self,name):
self.name=name
def __getattr__(self, item):
print("执行了__getattr__")
def __getattribute__(self, item):
print("执行了___getattribute__")
raise AttributeError("抛出了AttributeError异常")
if __name__ == '__main__':
animal=Animal("佩奇")
animal.name #属性存在
animal.aaaa #属性不存在
输出:
执行了___getattribute__
执行了__getattr__
执行了___getattribute__
执行了__getattr__