如何重写枚举构造函数?

2024-10-01 07:38:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创建一个存储二进制值的枚举,但我可以将任何值传递给它(它将存储value % 2

也就是说:我想使用Python3中的“官方”Enum类型,但要更改构造函数

我尝试了以下代码:

from enum import Enum

class Color(Enum):
    black = 0
    red = 1

    def __new__(cls, value):
        super().__new__(cls, value % 2)

    def __str__(self):
        return self.name

但我有一个错误:

>>> from ZCasino import *
ValueError: 0 is not a valid Couleur

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/felix/Téléchargements/ZCasino.py", line 12, in <module>
    class Couleur(Enum):
  File "/usr/lib/python3.8/enum.py", line 212, in __new__
    enum_member = __new__(enum_class, *args)
  File "/home/felix/Téléchargements/ZCasino.py", line 18, in __new__
    super().__new__(cls, value)
  File "/usr/lib/python3.8/enum.py", line 595, in __new__
    raise exc
  File "/usr/lib/python3.8/enum.py", line 579, in __new__
    result = cls._missing_(value)
  File "/usr/lib/python3.8/enum.py", line 608, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 0 is not a valid Couleur

Tags: inpynewisvaluelibusrline
3条回答

一个新的类方法可能比重写__new__更好:

class Color(Enum):
    black = 0
    red = 1

    @classmethod
    def from_int(cls, x):
        return cls(x%2)

然后

>>> Color.from_int(6)
<Color.black: 0>
>>> Color.from_int(7)
<Color.red: 1>

您需要在方法定义之后重写__new__方法

Is it possible to override __new__ in an enum to parse strings to an instance?

from enum import Enum

class Color(Enum):
    black = 0
    red = 1

    def __str__(self):
        return self.name

Couleur.__new__ = lambda cls, value: super(Couleur, cls).__new__(cls, value % 2)

您可以利用新的_missing_方法:

from aenum import Enum

class Color(Enum):
    black = 0
    red = 1
    #
    def __str__(self):
        return self.name
    #
    @classmethod
    def _missing_(cls, value):
        return cls(value % 2)

在使用中:

>>> list(Color)
[<Color.black: 0>, <Color.red: 1>]

>>> Color(3)
<Color.red: 1>

>>> Color(8)
<Color.black: 0>

_missing_是在Python 3.6中引入的。如果需要支持早期的python,可以使用^{}1

NB调用Color(7)时,您不是在创建新的Color,而是在获取创建枚举时创建的现有<Color.black: 0>


1披露:我是Python stdlib ^{}^{} backportAdvanced Enumeration (^{})图书馆的作者

相关问题 更多 >