Modify Enum to return value by default

91 views Asked by At

I am trying to modify Enum to return value by default:

class EnumDirectValueMeta(EnumMeta):
    def __getattribute__(cls, name):
        try:
            return object.__getattribute__(cls, name).value
        except AttributeError:
            return object.__getattribute__(cls, name)

class Currency(Enum, metaclass=EnumDirectValueMeta):
    USD = "USD"
    EUR = "EUR"
    GBP = "GBP"

So that I don't need to call Currency.USD.value, but only need to call Currency.USD to return "USD" (by default).

However, I always get RecursionError: maximum recursion depth exceeded while calling a Python object.

Tried also modifying __get__ instead to return self.value or return str(self.value), etc. same thing happens. I can't seem to find a way around getting into recursion.

Is there an elegant solution to this? Thanks.

EDIT:

Even though print(Currency.USD) prints string USD there are other issues.

Iterating trough Currency items with [ccy for ccy in Currency if ...] returns [Currency.USD, Currency.EUR, Currency.GBP] not the ['USD', 'EUR', 'GBP'] as it was intended. Now these list comprehensions are not so numerous and I can go around this with [ccy.value for ccy in Currency if ...] but seems like bad practice.

In Debug mode, I can see the ccy has value Currency.USD and trying to get balance[ccy] gives eror KeyError: <Currency.USD: 'USD'>

Seems to me basically the same as balance[Currency.USD] but that one works perfectly, as does balance['USD'], both returning the expected value.

1

There are 1 answers

0
Ethan Furman On

You can combine Enum and str to get what you want. See this answer for details.