如何强制抽象类的子类应该在 Python 中定义一个特定的内部类

How to enforce that subclass of abstract class should define a particular inner class in Python

提问人:Jagerber48 提问时间:10/15/2020 最后编辑:Jagerber48 更新时间:7/11/2022 访问量:352

问:

我有一个抽象类,子类将从中派生出来。具体的实现应该包括一个 Enum 类,其中包含一组命名常量。

from enum import Enum

class AbstractClass:
    def run(self)
        print('the values are:')
        for enum in ClassEnum:
            print(enum.value)
        self.speak()

    def speak(self):
       raise NotImplementedError
    

class ConcreteClassFirst(AbstractClass):
    class ClassEnum(Enum):
        RED = 0
        GREEN = 1
        BLUE = 2

    def speak(self)
        print('the colors are:')
        for enum in ClassEnum:
            print(enum.name)


class ConcreteClassSecond(AbstractClass):
    class ClassEnum(Enum):
        LION = 'scary'
        ELEPHANT = 'big'
        GIRAFFE = 'tall'

    def speak(self)
        print('the animals are:')
        for enum in ClassEnum:
            print(enum.name)

这段代码实际上给出了正确的行为,但是我希望有某种符号(类似于抽象方法)表明具体类的作者应该定义一个名为 .事实上,该方法需要它。NotImplementedErrorspeak()EnumClassEnumrun()

有些想法是要有类似的东西

class AbstractClass:
    class ClassEnum(Enum):
        pass

    def run(self):
    ...

但是,如果子类没有定义自己的 版本,这不会引发错误。我们可以试试ClassEnum

class AbstractClass:
    class ClassEnum(Enum):
        raise NotImplementedError

    def run(self):
    ...

但是,可以预见的是,一旦定义了AbstractClass

我可以试试

class AbstractClass:
    @property
    def ClassEnum(self):
        raise NotImplementedError

    def run(self):
    ...

但这里不清楚在子类中,ClassEnum 实际上应该是一个类。也许这种方法和一些文档可能是合适的。

Python 抽象 内部类

评论


答:

0赞 Jagerber48 7/11/2022 #1

我不认为 python 中除了奇怪的元类之外没有一种干净的方法来强制定义子类属性。 鉴于此,我认为下一个最好的办法是改用通过传递的实例属性。super.__init__()

from enum import Enum

class AbstractClass:
    def __init__(self, behavior_enum):
        """
        :param behavior_enum: enum class with values and names that determine class behavior
        """
        self.behavior_enum = behavior_enum

    def run(self)
        print('the values are:')
        for enum in self.behavior_enum:
            print(enum.value)
        self.speak()

    def speak(self):
       raise NotImplementedError
    

class ConcreteClassFirst(AbstractClass):
    class behavior_enum(Enum):
        RED = 0
        GREEN = 1
        BLUE = 2

    def __init__(self)
        super().__init__(self.behavior_enum)

    def speak(self)
        print('the colors are:')
        for enum in self.behavior_enum:
            print(enum.name)


class ConcreteClassSecond(AbstractClass):
    class behavior_enum(Enum):
        LION = 'scary'
        ELEPHANT = 'big'
        GIRAFFE = 'tall'

    def __init__(self)
        super().__init__(self.behavior_enum)

    def speak(self)
        print('the animals are:')
        for enum in self.behavior_enum:
            print(enum.name)