如何在python中定义抽象元类

问题描述

在python中定义抽象元类并像这样实例化时:

from abc import ABC,abstractmethod


class AbstractMetaClass(type,ABC):
    @abstractmethod
    def func(self):
        pass


class MyClass(Metaclass=AbstractMetaClass):
    pass

我原以为我的代码会失败,因为 MyClass 是一个抽象类的实例。相反,它运行没有问题。 发生了什么,我该怎么做?

解决方法

好吧,您只是发现它不起作用。你在想什么是有道理的:也许它应该失败。只是抽象类不是为了作为元类工作而设计的,而是与“类型”协同工作。我真的觉得不可思议,因为大多数 Python 对象机制在与元类一起使用时碰巧“正常工作” - 包括 properties,特殊的 dunder 方法,如 __getitem__ 和运算符方法等等。你只是遇到了一件没用的事情。

如果您的设计确实有意义,您可能只想手动检查“抽象元类”__init__ 方法中的抽象方法:

from abc import classmethod

class AbstractMetaClass(type):

    def __init__(cls,name,bases,ns,**kwargs):
        for meth_name,meth in cls.__class__.__dict__.items():
            if getattr(meth,"__isabstractmethod__",False):
                raise TypeError(f"Can't create new class {name} with no abstract classmethod {meth_name} redefined in the metaclass")
        return super().__init__(name,**kwargs)
        
    @abstractmethod
    def func(cls):
        pass

请注意,为了清楚起见,元类上的普通方法最好将“cls”作为第一个参数而不是“self”(尽管这可能是个人喜好)