如何将字符串与python枚举进行比较?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44781681/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 00:27:40  来源:igfitidea点击:

How to compare a string with a python enum?

pythonenumspython-3.6

提问by bli

I just discovered the existence of an Enumbase class in python and I'm trying to imagine how it could be useful to me.

我刚刚发现在 python 中存在一个Enum基类,我试图想象它对我有什么用处。

Let's say I define a traffic light status:

假设我定义了一个交通灯状态:

from enum import Enum, auto

class Signal(Enum):
    red = auto()
    green = auto()
    orange = auto()

Let's say I receive information from some subsystem in my program, in the form of a string representing a colour name, for instance brain_detected_colour = "red".

假设我从程序中的某个子系统接收信息,以表示颜色名称的字符串形式,例如brain_detected_colour = "red".

How do I compare this string to my traffic light signals?

我如何将此字符串与我的交通灯信号进行比较?

Obviously, brain_detected_colour is Signal.redis False, because Signal.redis not a string.

显然,brain_detected_colour is Signal.redis False,因为Signal.red不是字符串。

Signal(brain_detected_colour) is Signal.redfails with ValueError: 'red' is not a valid Signal.

Signal(brain_detected_colour) is Signal.red失败ValueError: 'red' is not a valid Signal

回答by bli

One does not create an instance of an Enum. The Signal(foo)syntax is used to access Enum members by value, which are not intended to be used when they are auto().

不会创建Enum实例。该Signal(foo)语法用于按值访问 Enum 成员,当它们是auto().

However one can use a string to access Enum memberslike one would access a value in a dict, using square brackets:

但是,可以使用字符串访问 Enum 成员,就像访问 a 中的值一样dict,使用方括号:

Signal[brain_detected_colour] is Signal.red

Another possibility would be to compare the string to the nameof an Enum member:

另一种可能性是将字符串与nameEnum 成员的进行比较:

# Bad practice:
brain_detected_colour is Signal.red.name

But here, we are not testing identity between Enum members, but comparing strings, so it is better practice to use an equality test:

但是在这里,我们不是测试 Enum 成员之间的身份,而是比较字符串,因此最好使用相等测试:

# Better practice:
brain_detected_colour == Signal.red.name

(The identity comparison between strings worked thanks to string interning, which is better not to be relied upon. Thanks @mwchase and @Chris_Rands for making me aware of that.)

(字符串之间的身份比较工作得益于字符串实习,最好不要依赖它。感谢@mwchase 和@Chris_Rands 让我意识到这一点。)

Yet another possibility would be to explicitly set the member values as their names when creating the Enum:

另一种可能性是在创建 Enum 时将成员值显式设置为其名称:

class Signal(Enum):
    red = "red"
    green = "green"
    orange = "orange"

(See this answerfor a method to have this automated.)

(有关使此自动化的方法,请参阅此答案。)

Then, Signal(brain_detected_colour) is Signal.redwould be valid.

那么,Signal(brain_detected_colour) is Signal.red就有效了。

回答by Ethan Furman

It is possible to have auto()return the name of the enum member as its value (which is in the autosection of the docs1:

可以auto()将枚举成员的名称作为其值返回(auto在文档1部分中

>>> class AutoName(Enum):
...     def _generate_next_value_(name, start, count, last_values):
...         return name
...

>>> class Ordinal(AutoName):
...     NORTH = auto()
...     SOUTH = auto()
...     EAST = auto()
...     WEST = auto()
...

>>> list(Ordinal)
[<Ordinal.NORTH: 'NORTH'>, <Ordinal.SOUTH: 'SOUTH'>, <Ordinal.EAST: 'EAST'>, <Ordinal.WEST: 'WEST'>]


1This requires version Python 3.6, or aenum2.02(aenumworks with Pythons as old as 2.7).

1这需要版本 Python 3.6 或aenum2.0 2aenum适用于 2.7 的 Python)。

2Disclosure: I am the author of the Python stdlib Enum, the enum34backport, and the Advanced Enumeration (aenum)library.

2披露:我是Python stdlibEnumenum34backportAdvanced Enumeration ( aenum)库的作者。