我主要是c#开发人员,但我目前正在用Python开发一个项目。
我如何在Python中表示等价的Enum ?
我主要是c#开发人员,但我目前正在用Python开发一个项目。
我如何在Python中表示等价的Enum ?
当前回答
这是我在这里找到的一个很好的Python食谱:http://code.activestate.com/recipes/577024-yet-another-enum-for-python/
def enum(typename, field_names):
"Create a new enumeration type"
if isinstance(field_names, str):
field_names = field_names.replace(',', ' ').split()
d = dict((reversed(nv) for nv in enumerate(field_names)), __slots__ = ())
return type(typename, (object,), d)()
使用示例:
STATE = enum('STATE', 'GET_QUIZ, GET_VERSE, TEACH')
更多细节可以在食谱页面上找到。
其他回答
我非常喜欢Alec Thomas的解决方案(http://stackoverflow.com/a/1695250):
def enum(**enums):
'''simple constant "enums"'''
return type('Enum', (object,), enums)
它看起来优雅而简洁,但它只是一个创建具有指定属性的类的函数。
通过对函数进行一些修改,我们可以让它表现得更像“枚举”:
注意:我通过尝试重现 pygtk的新样式'enums'的行为(如gtk . messagtype . warning)
def enum_base(t, **enums):
'''enums with a base class'''
T = type('Enum', (t,), {})
for key,val in enums.items():
setattr(T, key, T(val))
return T
这将基于指定类型创建枚举。除了像前面的函数那样提供属性访问外,它的行为与您期望Enum对类型的行为一样。它还继承了基类。
例如,整数enum:
>>> Numbers = enum_base(int, ONE=1, TWO=2, THREE=3)
>>> Numbers.ONE
1
>>> x = Numbers.TWO
>>> 10 + x
12
>>> type(Numbers)
<type 'type'>
>>> type(Numbers.ONE)
<class 'Enum'>
>>> isinstance(x, Numbers)
True
用这个方法还可以做一件有趣的事情,那就是通过覆盖内置方法来定制特定的行为:
def enum_repr(t, **enums):
'''enums with a base class and repr() output'''
class Enum(t):
def __repr__(self):
return '<enum {0} of type Enum({1})>'.format(self._name, t.__name__)
for key,val in enums.items():
i = Enum(val)
i._name = key
setattr(Enum, key, i)
return Enum
>>> Numbers = enum_repr(int, ONE=1, TWO=2, THREE=3)
>>> repr(Numbers.ONE)
'<enum ONE of type Enum(int)>'
>>> str(Numbers.ONE)
'1'
所以,我同意。让我们不要在Python中强制执行类型安全,但我想保护自己不犯愚蠢的错误。我们怎么想呢?
class Animal(object):
values = ['Horse','Dog','Cat']
class __metaclass__(type):
def __getattr__(self, name):
return self.values.index(name)
它使我在定义枚举时避免了值冲突。
>>> Animal.Cat
2
还有一个方便的优势:非常快速的反向查找:
def name_of(self, i):
return self.values[i]
如果你需要数值,这是最快的方法:
dog, cat, rabbit = range(3)
在Python 3中。X你也可以在最后添加一个星号占位符,它将吸收范围内所有剩余的值,以防你不介意浪费内存和无法计数:
dog, cat, rabbit, horse, *_ = range(100)
虽然最初的全会提案PEP 354在几年前被否决,但它不断被提出。本打算将某种enum添加到3.2,但它被推回到3.3,然后被遗忘。现在有一个PEP 435打算包含在Python 3.4中。PEP 435的参考实现是flufl.enum。
截至2013年4月,似乎有一个普遍的共识,即应该在3.4的标准库中添加一些东西——只要人们能够就“一些东西”应该是什么达成一致。这是最难的部分。看看从这里和这里开始的线程,以及2013年初的六个其他线程。
与此同时,每次出现这个问题时,PyPI、ActiveState等上都会出现大量的新设计和实现,所以如果你不喜欢FLUFL设计,可以尝试一下PyPI搜索。
从Python 3.4开始,正式支持枚举。您可以在Python 3.4文档页面上找到文档和示例。
枚举是使用类语法创建的,这使得它们很容易 读和写。中描述了另一种创建方法 功能的API。定义枚举,子类Enum如下所示:
from enum import Enum
class Color(Enum):
red = 1
green = 2
blue = 3