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

时间:2017-06-27 13:34:10

标签: python enums python-3.6

我刚刚在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.redValueError: 'red' is not a valid Signal失败。

4 个答案:

答案 0 :(得分:25)

一个人不会创建instance of an EnumSignal(foo)语法用于按值访问枚举成员,这些语法在auto()时无意使用。

然而,人们可以使用字符串access Enum members,就像使用方括号访问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"

(请参阅this answer了解自动化方法。)

然后,Signal(brain_detected_colour) is Signal.red有效。

答案 1 :(得分:13)

一种更好的做法是从Signal继承str

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

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

答案 2 :(得分:8)

可以让auto()返回枚举成员的名称作为其值(位于auto section of the docs 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.0 2 aenum与Pythons一起使用,只有2.7)。

2 披露:我是Python stdlib Enumenum34 backportAdvanced Enumeration (aenum)图书馆的作者。

答案 3 :(得分:1)

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