__getattr__()
class A:
def __getattr__(self,name):
print(f"getting {
name}")
raise AttributeError
o = A()
print(o.test)
程序调用一个对象的属性,当这个属性不存的时候希望程序做些什么,这里我们打印希望的属性,并且抛出异常
__getattribute__()
class A:
def __init__(self):
self.exist = True
def __getattribute__(self, item):
print(f"getting {
item}")
return None
o = A()
print(o.exist)
print(o.test)
只要尝试读取一个对象的属性,这个方法都会被调用,上面的演示表示,无论读取的属性是否存在都会被调用
class A:
def __init__(self):
self.exist = True
self.counter = 0
def __getattribute__(self, item):
if item == 'exist':
self.counter += 1
return super().__getattribute__(item)
o = A()
print(o.exist)
print(o.counter)
这里我们在魔术方法的返回值过程中不能直接调用__getattribute__()
方法,这样的话会无限递归。需要加 super
__setattr__()
添加或者修改属性就会触发他的执行
class A:
def __init__(self):
self.exist = True
self.counter = 0
def __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 = True
self.counter = 0
def __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 = True
self.counter = 0
def __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):
pass
o = A()
__set_name__()
class D:
def __set_name__(self, owner, name):
print(owner,name)
class A:
x = D()
o = A()
当我们在另一个类中去构建这个class的instance的时候,这个方法就会被调用,其实还是定义descripter