python - 覆盖扩展 Enum 的类的 __new__

标签 python enums overriding typeerror new-operator

Message 扩展了 Enum 以添加一些逻辑。两个重要的参数是详细级别和消息字符串,以及其他可选消息 (*args)。另一个类 MessageErrorMessage 类的特殊形式,其中详细级别始终为零,其他所有内容都相同。

以下代码尖叫TypeError:

TypeError: Enum.new() takes 2 positional arguments but 3 were given

from enum import Enum


class Message(Enum):
    verbose: int
    messages: list[str]

    def __new__(cls, verbose: int, message: str, *args):
        self = object.__new__(cls)
        self._value_ = message
        return self
    
    def __init__(self, verbose: int, message: str, *args):
        self.verbose = verbose
        self.messages = [self.value] + list(args)


class MessageError(Message):

    def __new__(cls, message: str):
        return super().__new__(cls, 0, message) # <- problem is here!

    def __init__(self, message: str):
        return super().__init__(0, message)


class Info(Message):
    I_001 = 2, 'This is an info'


class Error(MessageError):
    E_001 = 'This is an error'

我期望 super().__new__(cls, 0, message) 会从 Message 类调用 __new__,但它看来事实并非如此。我在这里做错了什么?

最佳答案

Enum在很多方面都是不寻常的(又名奇怪的),其中创造是最大的领域。在枚举类创建期间,在创建成员本身之后但在返回类之前,任何现有的 __new__重命名为__new_member__ 1__new__来自Enum本身被插入到类中——这就是这样的调用 Info('This is an error')将返回现有成员(或提高),而不创建新成员。

您的MessageError.__new__应该看起来像:

    def __new__(cls, message: str):
        return super().__new_member__(cls, 0, message)

1 在 3.11+ 中,它也保存为 _new_member_遵循枚举特定方法和属性的分解名称模式。


披露:我是 Python stdlib Enum 的作者, enum34 backport ,以及 Advanced Enumeration ( aenum )图书馆。

关于python - 覆盖扩展 Enum 的类的 __new__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76124622/

相关文章:

python-vlc 查找当前播放的音频

ios - Swift:正确处理登录错误状态?

c++ - 我如何制作和填充枚举类型的数组

python - 枚举行为与 Python 之间的区别

java - java中的方法重写中两个方法可以有不同的返回类型吗

java - 更改 Java 中重写方法的访问修饰符?

python - 如何将用户属性传递给 python 函数/路由 -- Flask

python - Python Numpy矩阵运算-矩阵[a == b]?

Powershell 从重写函数调用基类函数

python - 3D 直方图和等高线图 Python