编程语言
首页 > 编程语言> > python – 创建一个抽象的Enum类

python – 创建一个抽象的Enum类

作者:互联网

我正在尝试用抽象方法创建一个抽象枚举(实际上是Flag).
我的最终目标是能够根据我定义的基本枚举创建复合枚举的字符串表示.
我能够在不使类抽象的情况下获得此功能.

这是基本的Flag类和示例实现:

from enum import auto, Flag

class TranslateableFlag(Flag):
    @classmethod
    def base(cls):
        pass

    def translate(self):
        base = self.base()
        if self in base:
            return base[self]
        else:
            ret = []
            for basic in base:
                if basic in self:
                    ret.append(base[basic])
            return " | ".join(ret)

class Students(TranslateableFlag):
    ALICE = auto()
    BOB = auto()
    CHARLIE = auto()
    ALL = ALICE | BOB | CHARLIE

    @classmethod
    def base(cls):
        return {Students.ALICE: "Alice", Students.BOB: "Bob",
                Students.CHARLIE: "Charlie"}

一个示例用法是:

((Students.ALICE | Students.BOB).translate())
[Out]: 'Alice | Bob'

由于MetaClass冲突,切换到TranslateableFlag(Flag,ABC)失败.
(我不明白这个帖子 – Abstract Enum Class using ABCMeta and EnumMeta,所以我不确定它是否回答了我的问题).

我想以某种方式获得这样的功能:

@abstractclassmethod
@classmethod
    def base(cls):
        pass

是否有可能实现这一目标?

解决方法:

以下是如何使accepted answer适应问题Abstract Enum Class using ABCMeta and EnumMeta以创建所需的抽象枚举类:

from abc import abstractmethod, ABC, ABCMeta
from enum import auto, Flag, EnumMeta


class ABCEnumMeta(ABCMeta, EnumMeta):

    def __new__(mcls, *args, **kw):
        abstract_enum_cls = super().__new__(mcls, *args, **kw)
        try:  # Handle existence of undefined abstract methods.
            absmethods = list(abstract_enum_cls.__abstractmethods__)
            absmethods_str = ', '.join(f'{method!r}' for method in absmethods)
            plural = 's' if len(absmethods) > 1 else ''
            raise TypeError(
                f"cannot instantiate abstract class {abstract_enum_cls.__name__!r}"
                f" with abstract method{plural} {absmethods_str}")
        except AttributeError:
            pass
        return abstract_enum_cls


class TranslateableFlag(Flag, metaclass=ABCEnumMeta):

    @classmethod
    @abstractmethod
    def base(cls):
        pass

    def translate(self):
        base = self.base()
        if self in base:
            return base[self]
        else:
            ret = []
            for basic in base:
                if basic in self:
                    ret.append(base[basic])
            return " | ".join(ret)


class Students1(TranslateableFlag):
    ALICE = auto()
    BOB = auto()
    CHARLIE = auto()
    ALL = ALICE | BOB | CHARLIE

    @classmethod
    def base(cls):
        return {Students1.ALICE: "Alice", Students1.BOB: "Bob",
                Students1.CHARLIE: "Charlie"}


class Students2(TranslateableFlag):
    ALICE = auto()
    BOB = auto()
    CHARLIE = auto()
    ALL = ALICE | BOB | CHARLIE

# Abstract method not defined - should raise TypeError.
#    @classmethod
#    def base(cls):
#        ...

结果:

Traceback (most recent call last):
  ...
TypeError: cannot instantiate abstract class 'TranslateableFlag' with abstract method 'base'

标签:python-3-6,python,enums
来源: https://codeday.me/bug/20191001/1840451.html