How to get back name of the enum element?

PythonEnums

Python Problem Overview


I have an enum defined like this:

def enum(**enums):
    return type('Enum', (), enums)

Status = enum(
       STATUS_OK=0,
       STATUS_ERR_NULL_POINTER=1, 
       STATUS_ERR_INVALID_PARAMETER=2)

I have a function that returns status as Status enum. How can I get the name of the enum value, and not just value?

>>> cur_status = get_Status()
>>> print(cur_status)
1

I would like to get STATUS_ERR_NULL_POINTER, instead of 1

Python Solutions


Solution 1 - Python

You'd have to loop through the class attributes to find the matching name:

name = next(name for name, value in vars(Status).items() if value == 1)

The generator expression loops over the attributes and their values (taken from the dictionary produced by the vars() function) then returns the first one that matches the value 1.

Enumerations are better modelled by the enum library, available in Python 3.4 or as a backport for earlier versions:

from enum import Enum

class Status(Enum):
    STATUS_OK = 0
    STATUS_ERR_NULL_POINTER = 1 
    STATUS_ERR_INVALID_PARAMETER = 2

giving you access to the name and value:

name = Status(1).name  # gives 'STATUS_ERR_NULL_POINTER'
value = Status.STATUS_ERR_NULL_POINTER.value  # gives 1

Solution 2 - Python

2021 update: These answers are out of date. Using Python's standard Enum class,

cur_status.name

will return the name. (STATUS_ERR_NULL_POINTER)

To look up the enum knowing the name:

s = Status['STATUS_ERR_NULL_POINTER']

Solution 3 - Python

You don't need to loop through the Enum class but just access member_map.

>>> Status._member_map_['STATUS_OK']
<Status.STATUS_OK: 0>

Solution 4 - Python

Not sure which python version it was introduced, but the hidden attribute _value2member_map_ gives you what you want.

class Status(Enum):
    STATUS_OK=0
    STATUS_ERR_NULL_POINTER=1
    STATUS_ERR_INVALID_PARAMETER=2

str(Status._value2member_map_[1])

Out:

'Status.STATUS_ERR_NULL_POINTER'

Solution 5 - Python

For some reason, most of the methods above did not work for me. All methods return the Enum type as an integer. I'm working with Python 3.7.

In my solution, I defined class function to handle this. It's not purely pythonic, but worked well enough for my case.

from enum import Enum
    
class Status(Enum):
    STATUS_OK = 0
    STATUS_ERR_NULL_POINTER = 1 
    STATUS_ERR_INVALID_PARAMETER = 2
    
    @classmethod
    def name(cls,val):
        return { v:k for k,v in dict(vars(cls)).items() if isinstance(v,int)}.get(val,None)

# test it
stat = Status.STATUS_OK
print(Status.name(stat))

Prints: 'STATUS_OK'

It may seem obvious that we asked for the status after giving it the status, but in my case, this is set programmatically elsewhere

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMikeView Question on Stackoverflow
Solution 1 - PythonMartijn PietersView Answer on Stackoverflow
Solution 2 - PythongerardwView Answer on Stackoverflow
Solution 3 - PythontechneerView Answer on Stackoverflow
Solution 4 - PythonDeusXMachinaView Answer on Stackoverflow
Solution 5 - PythonRexBarkerView Answer on Stackoverflow