可以使用python的枚举类进行内联初始化吗

2024-06-11 21:18:45 发布

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

我试图通过修改来自https://docs.python.org/3.4/library/enum.html#interesting-examples的自动编号来执行一些C风格的枚举

我无法确定如何对__init__函数进行编码

class MyEnum (Enum):
    def __new__(cls):
        value = len(cls.__members__) + 1
        obj = object.__new__(cls)
        obj._value_ = value
        return obj

    def __new__(cls, value):
        super().__new__(cls, value) # It doesn't matter what I put here...

class ThingsToDo (MyEnum):
        first_thing = 30
        second_thing = ()
        ...
        another_thing = 50
        yet_another_thing = ()

等等,可以在初始化期间设置值。我尝试了很多不同的方法来定义__new__,但大多都会出现以下错误:

  File "/usr/lib/python3.7/enum.py", line 218, in __new__
      enum_member = __new__(enum_class, *args)
 TypeError: __new__() takes 1 positional argument but 2 were given

尽管上面代码中的调用给出了以下信息:

  File "/usr/lib/python3.7/enum.py", line 218, in __new__
    enum_member = __new__(enum_class, *args)
  File "./codecs.py", line 34, in __new__
    super().__new__(cls, value)
  File "/usr/lib/python3.7/enum.py", line 564, in __new__
    raise exc
  File "/usr/lib/python3.7/enum.py", line 548, in __new__
    result = cls._missing_(value)
  File "/usr/lib/python3.7/enum.py", line 577, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 30 is not a valid ThingsToDo

我要么错过了一些简单的东西,要么这是一个比我想象的更大的任务。我不受枚举的限制,所以如果有更好的方法,我愿意


Tags: inpyobjnewvaluelibusrdef
1条回答
网友
1楼 · 发布于 2024-06-11 21:18:45

希望您的第二个__new__应该是__init__,但这仍然是不正确的。您(可能)希望您的__new__看起来是:

    def __new__(cls, value=None):
        if value is None:
            value = len(cls.__members__) + 1
        obj = object.__new__(cls)
        obj._value_ = value
        return obj

但是,鉴于上述__new__,您的ThingsToDo枚举成员将是:

>>> list(ThingsToDo)
[
  <ThingsToDo.first_thing: 30>,
  <ThingsToDo.second_thing: 2>,
  <ThingsToDo.another_thing: 50>,
  <ThingsToDo.yet_another_thing: 4>,
  ]

注意secondyet_another_thing的值为24,而不是3151。如果这是你所期待的,那么你就可以走了

否则,如果要查找3151,则需要__new__从上次定义的枚举中查找值并递增:

    def __new__(cls, value=None):
        if value is None:
            if not cls.__members__:
                value = 1
            else:
                last_enum_name = cls._member_names_[-1]
                last_enum = cls.__members__[last_enum_name]
                value = last_enum.value + 1 
        obj = object.__new__(cls)
        obj._value_ = value
        return obj

相关问题 更多 >