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

问题描述 投票:0回答:5

我刚刚发现 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

python enums python-3.6
5个回答
108
投票

人们不会创建枚举的实例

Signal(foo)
语法用于按值访问 Enum 成员,当它们是
auto()
时不打算使用它们。

但是,可以使用字符串访问枚举成员,就像使用方括号访问

dict
中的值一样:

Signal[brain_detected_colour] is Signal.red

另一种可能性是将字符串与 Enum 成员的

name
进行比较:

# Bad practice:
brain_detected_colour is Signal.red.name

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

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

(字符串之间的身份比较之所以有效,要归功于 string interning,最好不要依赖它。感谢 @mwchase 和 @Chris_Rands 让我意识到这一点。)

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

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

(请参阅此答案,了解自动执行此操作的方法。)

那么,

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


86
投票

更好的做法是从

Signal
继承
str

class Signal(str, Enum):
    red = 'red'
    green = 'green'
    orange = 'orange'

brain_detected_colour = 'red'
brain_detected_colour == Signal.red  # direct comparison

34
投票

可以让

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

1 这需要 Python 3.6 版本,或

aenum
2.02
aenum
适用于 2.7 之前的 Python)。

2 披露:我是 Python stdlib

Enum
enum34
向后移植
高级枚举 (
aenum
)
库的作者。


2
投票
class Signal(Enum):
    red = auto()
    green = auto()
    orange = auto()

    def equals(self, string):
       return self.name == string

brain_detected_colour = "red"

if Signal.red.equals(brain_detected_colour):
   #something awesome

0
投票

从 Python 3.11 开始,您可以使用 StrEnum https://docs.python.org/3/library/enum.html#enum.StrEnum

from enum import StrEnum

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

然后完全按照你想要的方式使用

>>> "red" == Signal.red
True
>>> "orange" == Signal.red
False
© www.soinside.com 2019 - 2024. All rights reserved.