Python 如何管理类的创建行为

问题

如果我们要给类加上一个属性,只需在定义的时候加上属性就可以了:

class Animal:
    can_fly = True

如果这样的类有很多,我们可以定义一个父类,让其它类继承他就可以了:

class FlyAnimal:
    can_fly = True
    

class Bird(FlyAnima):
    pass

class Duck(FlyAnimal):
    pass

...

要是不想显示的定义这些属性,只需要根据名字或其它属性来定义它的 can_fly 属性呢?(虽然这样的做法如同产品的需求一样 BT)这就可以用到元类了。

解决方案

通常情况下,我们先定义类,然后进行实例化。如果有了元类,那么类就相当于元类的实例——也就是说,先有元类,然后才有类。

因此,我们就可以创建元类来实现对类创建行为的控制。那么如何定义元类来实现需求呢?以上文的问题来,可以做如下定义:

class AnimalMetaclass(type):
    
    def __new__(cls, name, bases, attrs):
        if name.lower() in ['bird', 'duck']:
            attrs['can_fly'] = True
        return type.__new__(cls, name, bases, attrs)
    

class Animal(object, metaclass=AnimalMetaclass):
    pass


class Bird(Animal):
    pass

下面让我们来试试效果:

>>> Bird.can_fly
True

看起来非常成功!

扩展

  • 元类需要继承自 type
  • __new__ 方法接收的参数分别为:
    • cls 当前准备创建类的对象
    • name 类的名字
    • bases 类的父类集合
    • attrs 类的属性字典
  • 使用元类时,通常会定义一个基类,用类指明元类,其它类继承自该基类即可
posted @ 2021-12-08 10:50  kingron  阅读(67)  评论(0编辑  收藏  举报