3

I am looking for an enum-based approach to return an array behind each enum item. For example, suppose that I need to specify a range for each type of target such as the following:

from enum import Enum 

class TargetRange(Enum):
    T1 = [0, 100]
    T2 = [30, 60]
    T3 = [50, 150]

Now, I am using the enum like the following:

target_range = TargetRange.T1
value = 140

# ...
# adjust the value

if(value > target_range[1]):
    value = target_range[1]
elif(value < target_range[0]):
    value = target_range[0]
# ...

But, I get the following error:

TypeError: 'TargetRange' object is not subscriptable

How can I resolve it? What is the correct usage of this kind of enum?

I should note that I found this post to return a string (instead of an array). Hence, I am looking for the same idea for returning array instead of a string.

OmG
  • 18,337
  • 10
  • 57
  • 90

2 Answers2

7

There are three ways to get support for indexing:

  • use the .value attribute

    TargetRange.T1.value
    
  • inherit from list as well as Enum:

    class TargetRange(list, Enum):
    
  • add the __getitem__ method:

    class TargetRange(Enum):
        def __getitem__(self, index):
            return self._value_[index]
        T1 = [0, 100]
        T2 = [30, 60]
        T3 = [50, 150]
    
    

It is also possible to add behavior to Python enums, which can simplify code elsewhere. For example:

class TargetRange(Enum):
    T1 = [0, 100]
    T2 = [30, 60]
    T3 = [50, 150]
    #
    def __getitem__(self, index):
        return self._value_[index]
    #
    def limit(self, value):
        # adjust the value
        if(value > self[1]):
            value = self[1]
        elif(value < self[0]):
            value = self[0]
        return value

then in the main code:

>>> TargetRange.T1.limit(140)
100

Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.

Ethan Furman
  • 63,992
  • 20
  • 159
  • 237
1

The difference between Enum and StrEnum is exactly at this point. If you print TargetRange.T1, you will find that the value of the enum item is not returned. Hence, a simple solution to resolve this issue is rewriting your first line of the code as follow:

target_range = TargtetRange.T1.value
#...

It means using .value property of the enum item instead of directly using the enum item.

OmG
  • 18,337
  • 10
  • 57
  • 90