我主要是c#开发人员,但我目前正在用Python开发一个项目。
我如何在Python中表示等价的Enum ?
我主要是c#开发人员,但我目前正在用Python开发一个项目。
我如何在Python中表示等价的Enum ?
当前回答
虽然最初的全会提案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搜索。
其他回答
这里是一个实现:
class Enum(set):
def __getattr__(self, name):
if name in self:
return name
raise AttributeError
下面是它的用法:
Animals = Enum(["DOG", "CAT", "HORSE"])
print(Animals.DOG)
下面是亚历克·托马斯解决方案的一个变种:
def enum(*args, **kwargs):
return type('Enum', (), dict((y, x) for x, y in enumerate(args), **kwargs))
x = enum('POOH', 'TIGGER', 'EEYORE', 'ROO', 'PIGLET', 'RABBIT', 'OWL')
assert x.POOH == 0
assert x.TIGGER == 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
所以,我同意。让我们不要在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]
从Python 3.4开始,正式支持枚举。您可以在Python 3.4文档页面上找到文档和示例。
枚举是使用类语法创建的,这使得它们很容易 读和写。中描述了另一种创建方法 功能的API。定义枚举,子类Enum如下所示:
from enum import Enum
class Color(Enum):
red = 1
green = 2
blue = 3