I'm trying to create an enum.Enum
with lazy evaluation.
According to the docs:
An enumeration is a set of symbolic names (members) bound to unique, constant values. Within an enumeration, the members can be compared by identity, and the enumeration itself can be iterated over.
I would say my case still falls within this definition. The values are still unique and constant, I would just like them to be initialised only when necessary. This could be because initialisation is time-consuming, relies on other Enum
members, has circular dependencies with other Enum
s, or (in my current case) because initialisation requires a running QGuiApplication
, and I would like my module to still be importable (but keep that specific enum unusable) if one is not running (there are of course other ways to get around this specific requirement, but I'd like to implement this Enum
class regardless).
Since we are only supposed to subclass EnumMeta
in rare cases, I wanted to do this by subclassing Enum
itself:
class Lazy:
def __init__(self, value):
self.value = value
class LazyEnum(Enum):
def __getattribute__(self, name):
result = super().__getattribute__(name)
if name == 'value' and isinstance(result, Lazy):
result = self._lazy_init(result.value)
self.__setattr__(name, result)
return result
The idea is to mark some values as Lazy
to be initialised later. However, my sample code:
class MyEnum(LazyEnum):
X = Lazy('x')
Y = Lazy('y')
Z = 'z'
def _lazy_init(self, value):
print(f"Evaluating {value}")
return value * 2
print(MyEnum.X.value)
print(MyEnum.X)
print(MyEnum.X.value)
raises the error:
AttributeError: can't set attribute
How would I get around this issue?