作者:49897801g9Iq | 来源:互联网 | 2023-01-31 10:19
我刚刚发现python中存在一个Enum基类,我试图想象它对我有用.
假设我定义了一个红绿灯状态:
from enum import Enum, auto
class Signal(Enum):
red = auto()
green = auto()
orange = auto()
假设我从程序中的某个子系统接收信息,例如以表示颜色名称的字符串的形式brain_detected_colour = "red"
.
如何将此字符串与我的红绿灯信号进行比较?
显然,brain_detected_colour is Signal.red
是False
因为Signal.red
不是一个字符串.
Signal(brain_detected_colour) is Signal.red
失败了ValueError: 'red' is not a valid Signal
.
1> bli..:
一个不创建枚举的实例.该Signal(foo)
语法用于按值访问Enum成员,这些成员不打算使用它们auto()
.
但是,可以使用字符串来访问Enum成员,就像dict
使用方括号访问a中的值一样:
Signal[brain_detected_colour] is Signal.red
另一种可能性是将字符串与name
Enum成员进行比较:
# Bad practice:
brain_detected_colour is Signal.red.name
但是在这里,我们不测试Enum成员之间的身份,而是比较字符串,因此最好使用相等性测试:
# Better practice:
brain_detected_colour == Signal.red.name
(由于字符串实习,字符串之间的身份比较有效,最好不要依赖.感谢@mwchase和@Chris_Rands让我意识到这一点.)
另一种可能性是在创建枚举时明确将成员值设置为其名称:
class Signal(Enum):
red = "red"
green = "green"
orange = "orange"
(有关将此方法自动化的方法,请参阅此答案.)
然后,Signal(brain_detected_colour) is Signal.red
将是有效的.
在`brain_detected_colour中使用`is`是Signal.red.name`是有风险的; 最好使用`==`.
你依赖于字符串实习,黑暗的实现细节http://guilload.com/python-string-interning/,永远不要使用`is`除非你真的需要比较对象的身份
解决了我的问题.虽然我不能使用`Signal(brain_detected_colour)是Signal.red`(在答案的最后提到,当用字符串值构建枚举时)......`Signal [brain_detected_colour] == Signal.red`确实有效然而.请注意,我考虑了评论说使用`==`进行比较风险较小.
2> Ethan Furman..:
可以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)
[, , , ]
1这需要版本Python 3.6或aenum
2.0 2(aenum
与Pythons一样长到2.7).
2披露:我是Python stdlibEnum
,enum34
backport和Advanced Enumeration(aenum
) 库的作者.