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

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


当前回答

这个解决方案是获取定义为列表的枚举类的简单方法(没有更多烦人的整数赋值):

enumeration.py:

import new

def create(class_name, names):
    return new.classobj(
        class_name, (object,), dict((y, x) for x, y in enumerate(names))
    )

example.py:

import enumeration

Colors = enumeration.create('Colors', (
    'red',
    'orange',
    'yellow',
    'green',
    'blue',
    'violet',
))

其他回答

在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

我通常使用的解决方案是这个简单的函数来获取动态创建的类的实例。

def enum(names):
    "Create a simple enumeration having similarities to C."
    return type('enum', (), dict(map(reversed, enumerate(
        names.replace(',', ' ').split())), __slots__=()))()

使用它非常简单,只需使用包含想要引用的名称的字符串调用函数即可。

grade = enum('A B C D F')
state = enum('awake, sleeping, dead')

这些值只是整数,因此如果需要可以利用它(就像在C语言中一样)。

>>> grade.A
0
>>> grade.B
1
>>> grade.F == 4
True
>>> state.dead == 2
True

保持简单,使用旧的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

在答案列表中没有看到这个,这是我想出的一个。它允许使用'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!

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

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

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