我主要是c#开发人员,但我目前正在用Python开发一个项目。

我如何在Python中表示等价的Enum ?


当前回答

另一个非常简单的Python枚举实现,使用namedtuple:

from collections import namedtuple

def enum(*keys):
    return namedtuple('Enum', keys)(*keys)

MyEnum = enum('FOO', 'BAR', 'BAZ')

,或者

# With sequential number values
def enum(*keys):
    return namedtuple('Enum', keys)(*range(len(keys)))

# From a dict / keyword args
def enum(**kwargs):
    return namedtuple('Enum', kwargs.keys())(*kwargs.values())




# Example for dictionary param:
values = {"Salad": 20, "Carrot": 99, "Tomato": "No i'm not"} 
Vegetables= enum(**values)

# >>> print(Vegetables.Tomato)        'No i'm not'


# Example for keyworded params: 
Fruits = enum(Apple="Steve Jobs", Peach=1, Banana=2)

# >>> print(Fruits.Apple)             'Steve Jobs'

就像上面子类设置的方法一样,这允许:

'FOO' in MyEnum
other = MyEnum.FOO
assert other == MyEnum.FOO

但是具有更大的灵活性,因为它可以有不同的键和值。这允许

MyEnum.FOO < MyEnum.BAR

如果使用填充连续数字值的版本,则按预期操作。

其他回答

Python没有内置的enum,其他答案有实现自己的enum的想法(您可能也对Python烹饪书中的顶部版本感兴趣)。

然而,在C中调用枚举的情况下,我通常只使用简单的字符串:由于对象/属性的实现方式,(C)Python已经优化为使用短字符串工作得非常快,因此使用整数并没有任何性能上的好处。为了防止输入错误/无效值,可以在选定的位置插入检查。

ANIMALS = ['cat', 'dog', 'python']

def take_for_a_walk(animal):
    assert animal in ANIMALS
    ...

(与使用类相比,一个缺点是您失去了自动完成的好处)

这是我在这里找到的一个很好的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')

更多细节可以在食谱页面上找到。

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)

在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

有关更多信息,请参阅提案。官方文件可能很快就会发布。

从Python 3.4开始,正式支持枚举。您可以在Python 3.4文档页面上找到文档和示例。

枚举是使用类语法创建的,这使得它们很容易 读和写。中描述了另一种创建方法 功能的API。定义枚举,子类Enum如下所示:

from enum import Enum
class Color(Enum):
     red = 1
     green = 2
     blue = 3