我主要是c#开发人员,但我目前正在用Python开发一个项目。
我如何在Python中表示等价的Enum ?
我主要是c#开发人员,但我目前正在用Python开发一个项目。
我如何在Python中表示等价的Enum ?
当前回答
保持简单,使用旧的Python 2。x(参见下面的Python 3!):
class Enum(object):
def __init__(self, tupleList):
self.tupleList = tupleList
def __getattr__(self, name):
return self.tupleList.index(name)
然后:
DIRECTION = Enum(('UP', 'DOWN', 'LEFT', 'RIGHT'))
DIRECTION.DOWN
1
在使用Python 3时保持简单:
from enum import Enum
class MyEnum(Enum):
UP = 1
DOWN = 2
LEFT = 3
RIGHT = 4
然后:
MyEnum.DOWN
参见:https://docs.python.org/3/library/enum.html
其他回答
def M_add_class_attribs(attribs):
def foo(name, bases, dict_):
for v, k in attribs:
dict_[k] = v
return type(name, bases, dict_)
return foo
def enum(*names):
class Foo(object):
__metaclass__ = M_add_class_attribs(enumerate(names))
def __setattr__(self, name, value): # this makes it read-only
raise NotImplementedError
return Foo()
像这样使用它:
Animal = enum('DOG', 'CAT')
Animal.DOG # returns 0
Animal.CAT # returns 1
Animal.DOG = 2 # raises NotImplementedError
如果你只想要唯一的符号,不关心值,替换这行:
__metaclass__ = M_add_class_attribs(enumerate(names))
用这个:
__metaclass__ = M_add_class_attribs((object(), name) for name in names)
在答案列表中没有看到这个,这是我想出的一个。它允许使用'in'关键字和len()方法:
class EnumTypeError(TypeError):
pass
class Enum(object):
"""
Minics enum type from different languages
Usage:
Letters = Enum(list('abc'))
a = Letters.a
print(a in Letters) # True
print(54 in Letters) # False
"""
def __init__(self, enums):
if isinstance(enums, dict):
self.__dict__.update(enums)
elif isinstance(enums, list) or isinstance(enums, tuple):
self.__dict__.update(**dict((v,k) for k,v in enumerate(enums)))
else:
raise EnumTypeError
def __contains__(self, key):
return key in self.__dict__.values()
def __len__(self):
return len(self.__dict__.values())
if __name__ == '__main__':
print('Using a dictionary to create Enum:')
Letters = Enum(dict((v,k) for k,v in enumerate(list('abcde'))))
a = Letters.a
print('\tIs a in e?', a in Letters)
print('\tIs 54 in e?', 54 in Letters)
print('\tLength of Letters enum:', len(Letters))
print('\nUsing a list to create Enum:')
Letters = Enum(list('abcde'))
a = Letters.a
print('\tIs a in e?', a in Letters)
print('\tIs 54 in e?', 54 in Letters)
print('\tLength of Letters enum:', len(Letters))
try:
# make sure we raise an exception if we pass an invalid arg
Failure = Enum('This is a Failure')
print('Failure')
except EnumTypeError:
print('Success!')
输出:
Using a dictionary to create Enum:
Is a in e? True
Is 54 in e? False
Length of Letters enum: 5
Using a list to create Enum:
Is a in e? True
Is 54 in e? False
Length of Letters enum: 5
Success!
Enum类可以是一行程序。
class Enum(tuple): __getattr__ = tuple.index
如何使用它(正向和反向查找、键、值、项等)
>>> State = Enum(['Unclaimed', 'Claimed'])
>>> State.Claimed
1
>>> State[1]
'Claimed'
>>> State
('Unclaimed', 'Claimed')
>>> range(len(State))
[0, 1]
>>> [(k, State[k]) for k in range(len(State))]
[(0, 'Unclaimed'), (1, 'Claimed')]
>>> [(k, getattr(State, k)) for k in State]
[('Unclaimed', 0), ('Claimed', 1)]
为什么枚举必须是整数?不幸的是,在不改变Python语言的情况下,我想不出任何好看的构造来生成它,所以我将使用字符串:
class Enumerator(object):
def __init__(self, name):
self.name = name
def __eq__(self, other):
if self.name == other:
return True
return self is other
def __ne__(self, other):
if self.name != other:
return False
return self is other
def __repr__(self):
return 'Enumerator({0})'.format(self.name)
def __str__(self):
return self.name
class Enum(object):
def __init__(self, *enumerators):
for e in enumerators:
setattr(self, e, Enumerator(e))
def __getitem__(self, key):
return getattr(self, key)
也许现在更好的是,为了配置文件或其他远程输入,我们可以自然地对字符串进行测试。
例子:
class Cow(object):
State = Enum(
'standing',
'walking',
'eating',
'mooing',
'sleeping',
'dead',
'dying'
)
state = State.standing
In [1]: from enum import Enum
In [2]: c = Cow()
In [3]: c2 = Cow()
In [4]: c.state, c2.state
Out[4]: (Enumerator(standing), Enumerator(standing))
In [5]: c.state == c2.state
Out[5]: True
In [6]: c.State.mooing
Out[6]: Enumerator(mooing)
In [7]: c.State['mooing']
Out[7]: Enumerator(mooing)
In [8]: c.state = Cow.State.dead
In [9]: c.state == c2.state
Out[9]: False
In [10]: c.state == Cow.State.dead
Out[10]: True
In [11]: c.state == 'dead'
Out[11]: True
In [12]: c.state == Cow.State['dead']
Out[11]: True
从Python 3.4开始,正式支持枚举。您可以在Python 3.4文档页面上找到文档和示例。
枚举是使用类语法创建的,这使得它们很容易 读和写。中描述了另一种创建方法 功能的API。定义枚举,子类Enum如下所示:
from enum import Enum
class Color(Enum):
red = 1
green = 2
blue = 3