有没有更简单的方法在Python 2中排序Enum成员?

时间:2018-04-26 17:45:30

标签: python python-2.7 enums

我坚持使用Python 2.7进行项目,我有几个Enum用于将Python框架(OpenERP)与遗留框架集成。在Python 2中,默认为Enums are not ordered

>>> from enum import Enum
>>> class Color(Enum):
...   RED = 1
...   GREEN = 2
...   BLUE = 3
... 
>>> list(Color)
[<Color.BLUE: 3>, <Color.RED: 1>, <Color.GREEN: 2>]

如果订单很重要,则必须手动添加_order_ = 'member1, member2, member3'属性。

>>> class Color(Enum):
...   _order_ = 'RED GREEN BLUE'
...   RED = 1
...   GREEN = 2
...   BLUE = 3
... 
>>> list(Color)
[<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 3>]

这适用于较小的Enum,但我有几个具有10到50个名字,并且在添加/删除名称时,无论是键入还是读取或保持顺序都太多了。< / p>

还有其他选择吗?

1 个答案:

答案 0 :(得分:2)

aenum 2.1.2 1 开始,_order_属性可以是一个函数;此函数将用作keysort(),以便Enum成员按正确顺序排列:

from aenum import Enum

class Pres(str, Enum):

    _init_ = 'value, precedence'        # footnote 2
    _order_ = lambda m: m.precedence    # footnote 3

    PRESIDENT = 'president', 1
    COUNSELOR_1 = 'first counselor', 2
    COUNSELOR_2 = 'second counselor', 3
    SECRETARY = 'secretary', 4

    def __repr__(self):
        "added so example below is clearer"
        return '<%s.%s>' % (self.__class__.__name__, self.name)

并在使用中:

>>> list(Pres)
[<Pres.PRESIDENT>, <Pres.COUNSELOR_1>, <Pres.COUNSELOR_2>, <Pres.SECRETARY>]

虽然我不会更容易调用下一版本,但如果您无法使用aenum,并且不想尝试维护庞大的_order_,则可以使用{{ 3}}:

Pres = Enum('Pres', (
        ('PRESIDENT', 'president'),          # comment here
        ('COUNSELOR_1', 'first counselor'),  # more comments here
        ('COUNSELOR_2', 'second counselor'), # you get the idea ;)
        ('SECRETARY', 'secretary'),
        ),
        type=str,
        )

def pres_repr(self):
    "added so example below is clearer"
    return '<%s.%s>' % (self.__class__.__name__, self.name)

Pres.__repr__ = pres_repr

丑陋,但它确实有效。但是,如果需要precedence字段,则无效。

1 披露:我是Functional APIPython stdlib Enumenum34 backport图书馆的作者。

在这种情况下,

2 _init_是必要的,因为我不希望将precedence值传递给str构造函数。

3 关键功能将被赋予一个参数:

  • _init_ - &gt; (name, value)的元组,其中值也可以是元组(在上面的例子中就是这样)
  • _init_ - &gt;包含字段aenum.NamedTuple的{​​{1}}以及name中的任何字段(上例中为_init_namevalue