首页 > 解决方案 > 即使实现了所有方法,我可以标记类摘要吗?

问题描述

有没有办法将 python 类标记为抽象或不可实例化,即使它的所有抽象方法都已实现?

class Component(ABC):
    @abstractmethod
    def operation(self) -> None:
        pass

class Decorator(Component): # I would like this class to be abstract
    def operation(self) -> None:
        print("basic operation")

我发现的唯一解决方法是在类中选择一些方法来同时具有实现和@abstractmethod装饰器,但是 python 需要子抽象类的派生来重新实现该方法。

这也可以通过让子类调用来解决super(),但pylint抱怨这是一个无用的调用。

class Component(ABC):
    @abstractmethod
    def operation(self) -> None:
        pass

class Decorator(Component): # I would like this class to be abstract
    @abstractmethod
    def operation(self) -> None:
        print("basic operation")

class ConcreteDecorator(Decorator): 
    def operation(self) -> None: # python makes child class re-implement
        super().operation()  # pylint complains about useless super delegation

有一个更好的方法吗?
我尝试使用带有实现和@abstractmethod装饰器的方法,但是派生类需要重新实现。我正在“编译时”寻找解决方案,而不是运行时错误。

标签: pythonabstract-classabc

解决方案


创建一个辅助类来覆盖该__new__函数以检查是否cls.__bases__包含自身。

class UnInstantiable:
    def __new__(cls, *args, **kwargs):
        if __class__ in cls.__bases__:
            raise TypeError(f"Can't instantiate un-instantiable class {cls.__name__}")

        return super().__new__(cls)

用法:

# class Decorator(Component):                # Add UnInstantiable base class
class Decorator(Component, UnInstantiable):  # like this
    def operation(self) -> None:
        print("basic operation")


Decorator()  # TypeError: Can't instantiate un-instantiable class Decorator

推荐阅读