如何在 Python 中表示“枚举”?

新手上路,请多包涵

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

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

原文由 John Rutherford 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 800
2 个回答

PEP 435 中所述, 枚举 已添加到 Python 3.4。它还在 pypi 上被 反向移植到 3.3、3.2、3.1、2.7、2.6、2.5 和 2.4

对于更高级的枚举技术,请尝试 aenum 库(2.7、3.3+,作者与 enum34 相同。代码在 py2 和 py3 之间并不完全兼容,例如你需要 __order__ 在 python 中2 ).

  • 要使用 enum34 ,请执行 $ pip install enum34
  • 要使用 aenum ,做 $ pip install aenum

安装 enum (无编号)将安装一个完全不同且不兼容的版本。


 from enum import Enum     # for enum34, or the stdlib version
# from aenum import Enum  # for the aenum version
Animal = Enum('Animal', 'ant bee cat dog')

Animal.ant  # returns <Animal.ant: 1>
Animal['ant']  # returns <Animal.ant: 1> (string lookup)
Animal.ant.name  # returns 'ant' (inverse lookup)

或等效地:

 class Animal(Enum):
    ant = 1
    bee = 2
    cat = 3
    dog = 4


在早期版本中,完成枚举的一种方法是:

 def enum(**enums):
    return type('Enum', (), enums)

像这样使用:

 >>> Numbers = enum(ONE=1, TWO=2, THREE='three')
>>> Numbers.ONE
1
>>> Numbers.TWO
2
>>> Numbers.THREE
'three'

您还可以轻松支持自动枚举,如下所示:

 def enum(*sequential, **named):
    enums = dict(zip(sequential, range(len(sequential))), **named)
    return type('Enum', (), enums)

并像这样使用:

 >>> Numbers = enum('ZERO', 'ONE', 'TWO')
>>> Numbers.ZERO
0
>>> Numbers.ONE
1

可以通过这种方式添加对将值转换回名称的支持:

 def enum(*sequential, **named):
    enums = dict(zip(sequential, range(len(sequential))), **named)
    reverse = dict((value, key) for key, value in enums.iteritems())
    enums['reverse_mapping'] = reverse
    return type('Enum', (), enums)

这会覆盖任何具有该名称的内容,但它对于在输出中呈现枚举很有用。如果反向映射不存在,它将抛出 KeyError 。第一个例子:

 >>> Numbers.reverse_mapping['three']
'THREE'


如果您使用 MyPy,另一种表达“枚举”的方法是使用 typing.Literal

例如:

 from typing import Literal #python >=3.8
from typing_extensions import Literal #python 2.7, 3.4-3.7

Animal = Literal['ant', 'bee', 'cat', 'dog']

def hello_animal(animal: Animal):
    print(f"hello {animal}")

hello_animal('rock') # error
hello_animal('bee') # passes

原文由 Alec Thomas 发布,翻译遵循 CC BY-SA 4.0 许可协议

在 PEP 435 之前,Python 没有等效项,但您可以实现自己的等效项。

我自己,我喜欢保持简单(我在网上看到了一些非常复杂的例子),像这样……

 class Animal:
    DOG = 1
    CAT = 2

x = Animal.DOG


在 Python 3.4 ( PEP 435 ) 中,您可以使 Enum 成为基类。这会为您提供一些额外的功能,如 PEP 中所述。例如,枚举成员不同于整数,它们由 namevalue 组成。

 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)


Enum 实现 可以转换为列表并且是可迭代的。其成员的顺序是声明顺序,与其值无关。例如:

 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

原文由 Alexandru Nedelcu 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题