10

关于如何在 Python 中实现枚举存在一些问题。大多数解决方案最终或多或少等同于以下内容:

class Animal:
    DOG=1
    CAT=2

其他人提出了更复杂的构造枚举的方法,但最终往往看起来像这个例子。

根据我在 Java 和 C# 方面的经验,我可以想到这种成语的各种用途。但是,它似乎不是很 Pythonic。事实上,似乎每次有人问为什么 Python 中没有枚举时,你往往会因为没有理由尝试在像 Python 这样的语言中强制执行编译时类型安全,而对预设的回答感到有点抱怨,或者需要枚举的设计在 Python 中是多么难闻。

我的问题不是如何在 Python 中实现枚举,而是一般来说人们如何以 Python 式的方式解决那些适合枚举的问题。换句话说,您将如何解决一个问题,该问题有助于拥有具有一组离散的可能值的数据类型,而无需将您的 Java/C# 解决方案移植到 Python。

4

4 回答 4

4

PEP 435刚刚被接受,它将 enum 包与 Enum 类和其他派生类(如 IntEnum)一起添加到标准库中。这意味着从 Python 3.4 开始,在设计中使用枚举的“pythonic”方式就是使用这个包。它看起来像这样:

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

>>> print(Color.red)
Color.red

>>> print(Color.red.name)
red

>>>> for color in Color:
....     print(color)
Color.red
Color.green
Color.blue

这种设计的关键特征是键可以拒绝没有意义的比较(与其他答案中建议的字符串键不同),允许键具有与键值无关的漂亮打印,以及赋予键值特殊除了在用户尝试使用 Enum 类中的非法键时引发显式且可理解的错误之外,还可以通过在 Enum 子类上定义方法来获得属性。

于 2013-05-10T14:21:26.883 回答
3

由于 Python 字符串是不可变的(并且 Python 会在必要时对它们进行实习),因此将数字枚举用于一组事物并没有真正的优势。相反,您可以简单地使用 a frozensetor tupleof 字符串(取决于您是否关心排序)。

另一方面,如果您关心的是命名空间,那么将事物属性设为类就可以了。

正如评论中提到的,如果您正在寻找状态机实现之类的东西,一流的功能是您的朋友。

于 2012-10-10T02:28:30.700 回答
2

由于不是来自 C# 或 Java 背景,我仍然不太了解这种对枚举的兴趣。

据我了解,我可能会退回到 django 风格,将任何必要的常量放在设置文件中并在必要时导入。

settings.py/animals.py

DOG = 1
CAT = 2

其他文件:

from animals import CAT, DOG

甚至...

设置.py

ANIMALS = { "DOG": 1, "CAT": 2}

其他文件:

from settings import ANIMALS

my_animal = "FROG"
if my_animal not in ANIMALS.keys():
    print "new species discovered!"
于 2012-10-10T02:22:35.307 回答
-1

我不相信 C# 中的枚举。对于状态机,您有策略模式。而不是查看对象的状态并决定要做什么。将要做什么的逻辑封装在对象本身中。

这是 Python 中的一种自然方法,对我来说,引入枚举只是在鼓励糟糕的代码。

于 2014-09-30T22:24:48.137 回答