自动编号从0开始的枚举

时间:2016-12-22 20:04:28

标签: python python-3.x

有没有更好的方法来创建一个从0开始自动编号的长枚举列表?我能找到的最接近的是:

class Color(Enum):
    red, green, blue=range(3)

但是,上述方法需要预先知道枚举中的总项目。

5 个答案:

答案 0 :(得分:6)

The documentation提供了一个自动编号的方法,可以很容易地从零开始调整:

class AutoNumber(Enum):
     def __new__(cls):
        value = len(cls.__members__)  # note no + 1
        obj = object.__new__(cls)
        obj._value_ = value
        return obj

然后你可以用任意成员创建它:

class Color(AutoNumber):
    red = ()
    green = ()
    blue = ()

或者,请注意functional API可以采用可迭代的键值对:

from itertools import count

Color = Enum('Color', zip(['red', 'green', 'blue'], count()))

itertools.count基本上是range的开放式等价物。

但是,文档还提供了成员通常以1开头的原因:

  

默认为1作为起始编号而不是0的原因是   0在布尔意义上是False,但枚举成员都评估为   True

从零开始可能会导致以后混淆行为。

答案 1 :(得分:2)

如@jonrsharpe所示,可以这样创建一个枚举:

Color = Enum('Color', ['RED', 'GREEN', 'BLUE'])

这将以1索引(开始)。

从Python 3.5开始,official documentation状态:

使用start参数指定其他起始值

如文档所述,您可以完全做到这一点:

Color = Enum('Color', ['RED', 'GREEN', 'BLUE'], start=0)

答案 2 :(得分:2)

OP澄清说,他们的动机是将枚举值用作数组索引,这意味着从零开始的连续编号。

documentation指出:

默认[自动编号]方法的目标是 按照提供的最后一个int顺序提供下一个int,但是 这样做的方式是实现细节,并且可能会更改

因此,明智的做法是明确定义自动编号方法,例如:

from enum import IntEnum, auto

class PrimaryColours(IntEnum):
    def _generate_next_value_(self, _start, count, _last_values):
        """Generate consecutive automatic numbers starting from zero."""
        return count

    RED = auto()
    GREEN = auto()
    BLUE = auto()

然后:

orange = (255, 102, 0)
print(orange[PrimaryColours.GREEN])

> 102

答案 3 :(得分:2)

如果您更喜欢以老式的方式声明一个类,在 Python 3.6.4 中,您可以尝试这样的方法:

from enum import Enum, auto

class MyEnum(Enum):
    FIELD_1 = 0
    FIELD_2 = auto()
    FIELD_3 = auto()

print(list(MyEnum))

应该导致:

>> [<MyEnum.FIELD_1: 0>, <MyEnum.FIELD_2: 1>, <MyEnum.FIELD_3: 2>]

如果您没有将 FIELD_1 设置为 0,则枚举属性值应从 1 开始。

答案 4 :(得分:0)

只需这样做

from enum import IntEnum

color = IntEnum('color', ['red', 'green', 'blue'], start=0)

或者如果您想参加一堂课

class Color (IntEnum):
    def __init__(*args, **kwargs):
        start = kwargs.pop('start', None)
        if start is None:
            kwargs['start'] = 0
        super().__init__(*args, **kwargs)