我主要是c#开发人员,但我目前正在用Python开发一个项目。
我如何在Python中表示等价的Enum ?
我主要是c#开发人员,但我目前正在用Python开发一个项目。
我如何在Python中表示等价的Enum ?
当前回答
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)]
其他回答
在PEP 435之前,Python没有等效的,但你可以实现自己的。
就我个人而言,我喜欢保持简单(我在网上看到过一些非常复杂的例子),就像这样……
class Animal:
DOG = 1
CAT = 2
x = Animal.DOG
在Python 3.4 (PEP 435)中,可以将Enum作为基类。这为您提供了一些额外的功能,详见PEP。例如,enum成员不同于整数,它们由名称和值组成。
from enum import Enum
class Animal(Enum):
DOG = 1
CAT = 2
print(Animal.DOG)
# <Animal.DOG: 1>
print(Animal.DOG.value)
# 1
print(Animal.DOG.name)
# "DOG"
如果您不想键入值,请使用以下快捷方式:
class Animal(Enum):
DOG, CAT = range(2)
枚举实现可以转换为列表,并且是可迭代的。其成员的顺序是声明顺序,与它们的值无关。例如:
class Animal(Enum):
DOG = 1
CAT = 2
COW = 0
list(Animal)
# [<Animal.DOG: 1>, <Animal.CAT: 2>, <Animal.COW: 0>]
[animal.value for animal in Animal]
# [1, 2, 0]
Animal.CAT in Animal
# True
Davidg建议使用词典。我想更进一步,使用集合:
months = set('January', 'February', ..., 'December')
现在你可以测试一个值是否与集合中的一个值匹配,如下所示:
if m in months:
但是,像dF,我通常只使用字符串常量来代替枚举。
这是我见过的最好的一个:“Python中的First Class Enums”
http://code.activestate.com/recipes/413486/
It gives you a class, and the class contains all the enums. The enums can be compared to each other, but don't have any particular value; you can't use them as an integer value. (I resisted this at first because I am used to C enums, which are integer values. But if you can't use it as an integer, you can't use it as an integer by mistake so overall I think it is a win.) Each enum is a unique value. You can print enums, you can iterate over them, you can test that an enum value is "in" the enum. It's pretty complete and slick.
编辑(cfi):上面的链接不兼容Python 3。下面是我将枚举.py移植到Python 3的端口:
def cmp(a,b):
if a < b: return -1
if b < a: return 1
return 0
def Enum(*names):
##assert names, "Empty enums are not supported" # <- Don't like empty enums? Uncomment!
class EnumClass(object):
__slots__ = names
def __iter__(self): return iter(constants)
def __len__(self): return len(constants)
def __getitem__(self, i): return constants[i]
def __repr__(self): return 'Enum' + str(names)
def __str__(self): return 'enum ' + str(constants)
class EnumValue(object):
__slots__ = ('__value')
def __init__(self, value): self.__value = value
Value = property(lambda self: self.__value)
EnumType = property(lambda self: EnumType)
def __hash__(self): return hash(self.__value)
def __cmp__(self, other):
# C fans might want to remove the following assertion
# to make all enums comparable by ordinal value {;))
assert self.EnumType is other.EnumType, "Only values from the same enum are comparable"
return cmp(self.__value, other.__value)
def __lt__(self, other): return self.__cmp__(other) < 0
def __eq__(self, other): return self.__cmp__(other) == 0
def __invert__(self): return constants[maximum - self.__value]
def __nonzero__(self): return bool(self.__value)
def __repr__(self): return str(names[self.__value])
maximum = len(names) - 1
constants = [None] * len(names)
for i, each in enumerate(names):
val = EnumValue(i)
setattr(EnumClass, each, val)
constants[i] = val
constants = tuple(constants)
EnumType = EnumClass()
return EnumType
if __name__ == '__main__':
print( '\n*** Enum Demo ***')
print( '--- Days of week ---')
Days = Enum('Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su')
print( Days)
print( Days.Mo)
print( Days.Fr)
print( Days.Mo < Days.Fr)
print( list(Days))
for each in Days:
print( 'Day:', each)
print( '--- Yes/No ---')
Confirmation = Enum('No', 'Yes')
answer = Confirmation.No
print( 'Your answer is not', ~answer)
在2013-05-10,Guido同意将PEP 435纳入Python 3.4标准库。这意味着Python终于内置了对枚举的支持!
Python 3.3、3.2、3.1、2.7、2.6、2.5和2.4有一个可用的后端端口。它在Pypi上枚举34。
声明:
>>> from enum import Enum
>>> class Color(Enum):
... red = 1
... green = 2
... blue = 3
表示:
>>> print(Color.red)
Color.red
>>> print(repr(Color.red))
<Color.red: 1>
迭代:
>>> for color in Color:
... print(color)
...
Color.red
Color.green
Color.blue
编程访问:
>>> Color(1)
Color.red
>>> Color['blue']
Color.blue
有关更多信息,请参阅提案。官方文件可能很快就会发布。
虽然最初的全会提案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搜索。