简体   繁体   English

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

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

I have an abstract class from which subclasses will derive.我有一个抽象类,子类将从中派生。 The concrete implementations should include within them an Enum class which holds a set of named constants.具体实现应该在其中包含一个 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)

this code in fact gives the correct behaviour, however I would like there to be some sort of notation (similar to the NotImplementedError on the abstract speak() method) That indicates the author of the concrete class should define an inner Enum class called ClassEnum .这段代码实际上给出了正确的行为,但是我希望有某种符号(类似于抽象speak()方法上的NotImplementedError ),这表明具体类的作者应该定义一个名为ClassEnum的内部Enum类。 It is needed in fact for the run() method.实际上run()方法需要它。

Some ideas are to have something like有些想法是有类似的东西

class AbstractClass:
    class ClassEnum(Enum):
        pass

    def run(self):
    ...

but this won't raise an error if the subclass doesn't define its own version of ClassEnum .但是如果子类没有定义自己的ClassEnum版本,这不会引发错误。 We could try我们可以试试

class AbstractClass:
    class ClassEnum(Enum):
        raise NotImplementedError

    def run(self):
    ...

But this predictably raises an error as soon as the AbstractClass is defined但是一旦定义了AbstractClass就可以预见地引发错误

I could try我可以试试

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

    def run(self):
    ...

But here it's not clear that in the subclass ClassEnum should in fact be a class.但是这里不清楚子类中的 ClassEnum 实际上应该是一个类。 Perhpas this approach with some documentation could be appropriate.. Perhpas 这种带有一些文档的方法可能是合适的..

I don't think there's a clean way in python short of strange metaclasses to enforce definition of class attributes on subclasses.我认为没有奇怪的元类在python中没有一种干净的方法来强制定义子类上的类属性。 Given that, I think the next best thing is to instead use instance attributes passed through super.__init__() .鉴于此,我认为下一个最好的方法是使用通过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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python3 - 如何从现有抽象类定义抽象子类? - Python3 - How does one define an abstract subclass from an existing abstract class? 如何使用 __init_subclass__ 而不是 ABCMeta 强制子类实现父类的抽象方法? - How to enforce a subclass to implement a parent class' abstract methods using __init_subclass__ instead of ABCMeta? 在Python中,如何强制抽象方法在子类上是静态的? - In Python, how to enforce an abstract method to be static on the child class? 如何在 Python 中为抽象类定义构造函数实现? - How define constructor implementation for an Abstract Class in Python? 如何子类化两个父类的内部类以在子类 class 上正确定义内部 class? - How do I subclass two parent classes' inner classes to correctly define an inner class on a child class? 检测抽象 class、python 的不完整子类 - Detect incomplete subclass of abstract class, python 子类抽象类 - Subclass Abstract Class 抽象类可以是子类吗? - Can an abstract class be a subclass? 如何在python中定义一个抽象类并强制实现变量 - how to define an abstract class in python and force implement variables Python中是否有“Addable”协议或抽象基class? 如果不是,人们将如何定义它? - Is there an "Addable" protocol or abstract base class in Python? If not how would one define it?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM