Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare a string with a python enum?

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

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".

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

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

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

like image 575
bli Avatar asked Jun 27 '17 13:06

bli


People also ask

Can enum be compared with string?

For comparing String to Enum type you should convert enum to string and then compare them. For that you can use toString() method or name() method. toString()- Returns the name of this enum constant, as contained in the declaration.

Can enum variable be compared?

We can compare enum variables using the following ways. Using Enum. compareTo() method. compareTo() method compares this enum with the specified object for order.


2 Answers

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().

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

Signal[brain_detected_colour] is Signal.red 

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

# 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:

# 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.)

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

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

(See this answer for a method to have this automated.)

Then, Signal(brain_detected_colour) is Signal.red would be valid.

like image 141
bli Avatar answered Sep 19 '22 09:09

bli


A better practice is to inherit Signal from str:

class Signal(str, Enum):     red = 'red'     green = 'green'     orange = 'orange'  brain_detected_colour = 'red' brain_detected_colour == Signal.red  # direct comparison 
like image 40
Mushif Ali Nawaz Avatar answered Sep 21 '22 09:09

Mushif Ali Nawaz