python魔术方法(二)
__getattr__()
class A:def __getattr__(self,name):print(f"getting {name}")raise AttributeErroro = A()
print(o.test)
程序调用一个对象的属性,当这个属性不存的时候希望程序做些什么,这里我们打印希望的属性,并且抛出异常
__getattribute__()
class A:def __init__(self):self.exist = Truedef __getattribute__(self, item):print(f"getting {item}")return Noneo = A()
print(o.exist)
print(o.test)
只要尝试读取一个对象的属性,这个方法都会被调用,上面的演示表示,无论读取的属性是否存在都会被调用
class A:def __init__(self):self.exist = Trueself.counter = 0def __getattribute__(self, item):if item == 'exist':self.counter += 1return super().__getattribute__(item)o = A()
print(o.exist)
print(o.counter)
这里我们在魔术方法的返回值过程中不能直接调用__getattribute__()
方法,这样的话会无限递归。需要加 super
__setattr__()
添加或者修改属性就会触发他的执行
class A:def __init__(self):self.exist = Trueself.counter = 0def __setattr__(self, key, value):print(f"key is {key} value is {value}")super().__setattr__(key, value)o = A()
o.exist = False
print(o.exist)
__delattr__()
在一个对象正常产生和消亡的过程中,这个函数是不会被调用的,这个是在我们尝试删除一个对象的属性的时候才会被调用。
class A:def __init__(self):self.exist = Trueself.counter = 0def __delattr__(self, item):print(f"del {item}")super().__delattr__(item)o = A()
del o.exist
__dir__()
dir
方法用来返回所有可用的属性或者方法,python规定这个方法必须返回一个sequence
,最常见的sequence
就是列表了,我们这里就返回一个列表
class A:def __init__(self):self.exist = Trueself.counter = 0def __dir__(self):lst = super().__dir__()return [el for el in lst if not el.startswith("_")]o = A()
print(dir(o))
__slots__
这个不算是一个方法,是一个属性,它规定了这个类中可以有那些自定义的 attribute
,是一个白名单机制
__init_subclass__()
这个方法要定义在基类中,当我们以这个类为基类,创建衍生类的时候,就会调用这个方法
class Base:def __init_subclass__(cls, **kwargs):print(cls)class A(Base):passo = A()
__set_name__()
class D:def __set_name__(self, owner, name):print(owner,name)class A:x = D()o = A()
当我们在另一个类中去构建这个class的instance的时候,这个方法就会被调用,其实还是定义descripter