python魔术方法(二)

__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

猜你喜欢

转载自blog.csdn.net/weixin_43903639/article/details/129087823