Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I keep track of Python enum values internally?

My end goal really is to create a helper method in my Enum class that always returns an Enum member and never raises an exception, given whatever possible value, e.g.

Color.from_value('red')

In case the value is not part of the enum, the helper method will return a default one, say Color.UNKNOWN.

Based on this answer from another related question, I can do checks on the values by listing them through some built-in members. However, what I want to do next is to keep track of all the values in an internal member so that I don't have to always iterate through the values every time the helper method is called. I tried doing something similar to the following:

class Color(Enum):
    RED = 'red'
    BLUE = 'blue'
    GREEN = 'green'

    # this doesn't work
    _values = [item.value for item in Color]

and as expected, it doesn't work. Is this perhaps something that's already built-in in Python Enums?

like image 473
Psycho Punch Avatar asked Oct 17 '22 11:10

Psycho Punch


1 Answers

You can create the method and check for the values in the class:

import enum

class Color(enum.Enum):
    RED = 'red'
    BLUE = 'blue'
    GREEN = 'green'
    UNKNOWN = "unknown"

    @classmethod
    def from_value(cls, value):
      try:
        return {item.value: item for item in cls}[value]
      except KeyError:
        return cls.UNKNOWN

print(Color.from_value("hey"))
print(Color.from_value("red"))

Results:

Color.UNKNOWN
Color.RED

Here you have a live example

In case you dont want to reiterate, you can always have an outside cache of the values:

class Color(enum.Enum):
    RED = 'red'
    BLUE = 'blue'
    GREEN = 'green'
    UNKNOWN = "unknown"

    @classmethod
    def from_value(cls, value):
      try:
        return _COLORITEMS[value]
      except KeyError:
        return cls.UNKNOWN
_COLORITEMS = {item.value: item for item in Color}
like image 73
Netwave Avatar answered Nov 15 '22 05:11

Netwave