1、__getattr__()
当调用一个不存在的属性时,就会触发__getattr__()
只有在使用点调用属性且属性不存在的时候才会触发
class Foo:
x = 1
def __init__(self, y):
self.y = y
def __getattr__(self, item):
print("执行__getattr__()")
print("不存在",item)
f1 = Foo(10)
print(f1.x) # 调用存在的属性不会触发__getattr__()
f1.dsa # 因为dsa属性不存在,所以会触发__getattr__(),将f1传给self,dsa传给item
结果:
1
执行__getattr__()
不存在 dsa
2、__ setattr__()
在改动属性或新增属性的时候会触发__setattr__()
添加/修改属性会触发它的执行
class Foo:
x = 1
def __init__(self, y):
self.y = y
def __getattr__(self, item):
print("执行__getattr__()")
print("不存在", item)
def __setattr__(self, key, value):
print("执行__setattr__()")
# self.key = value # 这样写会进入死递归
self.__dict__[key] = value
def __delattr__(self, item):
print("执行__delattr__()")
self.__dict__.pop(item)
f1 = Foo(10) # 执行__setattr__()
print(f1.__dict__) # {'y': 10}
3、__ delattr__()
删除一个属性的时候会触发__delattr__()
删除属性的时候会触发
class Foo:
x = 1
def __init__(self, y):
self.y = y
def __getattr__(self, item):
print("执行__getattr__()")
print("不存在", item)
def __delattr__(self, item):
print("执行__delattr__()")
# del self.item 这样写会进入死递归
self.__dict__.pop(item)#这是删除操作的本质
f1 = Foo(10)
del f1.y # 执行__delattr__()
print(f1.__dict__) # {}
综合演示:
示例1:
class Foo:
x=1
def __init__(self,y):
self.y=y
def __getattr__(self, item):
print('----> from getattr:你找的属性不存在')
def __setattr__(self, key, value):
print('----> from setattr')
# self.key=value #这就无限递归了,你好好想想
# self.__dict__[key]=value #应该使用它
def __delattr__(self, item):
print('----> from delattr')
# del self.item #无限递归了
self.__dict__.pop(item)
# __setattr__添加/修改属性会触发它的执行
f1=Foo(10)
print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
f1.z=3
print(f1.__dict__)
# __delattr__删除属性的时候会触发
f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作
del f1.a
print(f1.__dict__)
# __getattr__只有在使用点调用属性且属性不存在的时候才会触发
f1.xxxxxx
1、这些双下划线开头的方法都是类内置的方法,可以通过dir(object)函数来查看
2、所有类内函数,都是如果有定义先调用定义的,没有定义则调用默认的
3、相对而言__getattr__()函数更有用,其他两个函数用的比较少
4、双下划綫开头的方法,只有在类的实例调用的时候才会触发
示例2:当属性不存在时,不报错
class Foo:
x = 1
def __init__(self, y):
self.y = y
def __getattr__(self, item):
print("执行__getattr__()")
print("不存在", item)
f1 = Foo(10)
f1.age
结果:
执行__getattr__()
不存在 age
示例3:所有属性都要求是字符串
class Foo:
x = 1
def __init__(self, y):
self.y = y
def __setattr__(self, key, value):
if type(value) is str:
self.__dict__[key] = value
print("设置成功")
else:
print("属性内容必须是字符串,设置失败")
f1 = Foo(10) # 属性内容必须是字符串,设置失败
f2 = Foo("CJJ") # 设置成功
示例4:所有属性都不允许删除
class Foo:
x = 1
def __init__(self, y):
self.y = y
def __delattr__(self, item):
print("所有属性不允许删除")
f1 = Foo(10)
f1.name = "CJJ"
del f1.name # 所有属性不允许删除