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

2024-05-23 17:41:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我刚刚在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.redFalse,因为Signal.red不是字符串。

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


Tags: 字符串fromautosignal定义is状态enum
2条回答

可以让auto()返回枚举成员的名称作为其值(位于^{} section of the docs1中):

>>> 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'>]

1这需要Python 3.6版本,或者aenum2.02aenum与2.7版本的Python一起工作)。

2披露:我是Python stdlib ^{}^{} backportAdvanced Enumeration (^{})库的作者。

不能创建instance of an EnumSignal(foo)语法用于按值访问枚举成员,当它们是auto()时,不打算使用这些值。

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

Signal[brain_detected_colour] is Signal.red

另一种可能是将字符串与枚举成员的name进行比较:

# Bad practice:
brain_detected_colour is Signal.red.name

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

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

(字符串之间的身份比较由于string interning而起作用,最好不要依赖它。感谢@mwchase和@Chris戆Rands让我意识到这一点。)

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

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

(请参见this answer以获取自动执行此操作的方法。)

那么,Signal(brain_detected_colour) is Signal.red将是有效的。

相关问题 更多 >