带有属性的python枚举

python enums with attributes

考虑:

1
2
3
4
5
6
7
8
class Item:
   def __init__(self, a, b):
       self.a = a
       self.b = b

class Items:
    GREEN = Item('a', 'b')
    BLUE = Item('c', 'd')

有没有一种方法可以使简单枚举的思想适应这种情况?(看到这个问题)理想地,就像在Java中一样,我想把它全部塞进一个类。

Java模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
enum EnumWithAttrs {
    GREEN("a","b"),
    BLUE("c","d");

    EnumWithAttrs(String a, String b) {
      this.a = a;
      this.b = b;
    }

    private String a;
    private String b;

    /* accessors and other java noise */
}


3.4新的Python数据类型(枚举有一个增强的enum34已backported的aenum1)。你很容易地支持和两个enum34aenum2用例:

[ 3 ] aenum

1
2
3
4
5
import aenum
class EnumWithAttrs(aenum.AutoNumberEnum):
    _init_ = 'a b'
    GREEN = 'a', 'b'
    BLUE = 'c', 'd'

[ enum34细/ 3或stdlib enum3.4 + ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import enum
class EnumWithAttrs(enum.Enum):

    def __new__(cls, *args, **kwds):
        value = len(cls.__members__) + 1
        obj = object.__new__(cls)
        obj._value_ = value
        return obj

    def __init__(self, a, b):
        self.a = a
        self.b = b

    GREEN = 'a', 'b'
    BLUE = 'c', 'd'

与使用:

1
2
3
4
5
--> EnumWithAttrs.BLUE
<EnumWithAttrs.BLUE: 1>

--> EnumWithAttrs.BLUE.a
'c'

1披露的作者:我是在Python程序enum34Enum,维护,和先进的计数(aenum)库。

2、aenum还支持基于NamedTuplesNamedConstants元类。


使用namedtuple:

1
2
3
4
5
6
7
from collections import namedtuple

Item = namedtuple('abitem', ['a', 'b'])

class Items:
    GREEN = Item('a', 'b')
    BLUE = Item('c', 'd')


3:在Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Status(Enum):
    READY ="ready","I'm ready to do whatever is needed"
    ERROR ="error","Something went wrong here"

    def __new__(cls, *args, **kwds):
        obj = object.__new__(cls)
        obj._value_ = args[0]
        return obj

    # ignore the first param since it's already set by __new__
    def __init__(self, _: str, description: str = None):
        self._description_ = description

    def __str__(self):
        return self.value

    # this makes sure that the description is read-only
    @property
    def description(self):
        return self._description_

你可以使用它的标准或厂用枚举类型:

1
2
3
4
5
6
print(Status.READY)
# ready
print(Status.READY.description)
# I'm ready to do whatever is needed
print(Status("ready")) # this does not create a new object
# ready