Я много осматривался и не смог найти хорошего решения этой проблемы, используя класс Enum
, который вы пытаетесь использовать. Однако, если вы хотите отказаться от идеи использования Enum
в качестве суперкласса, вы можете использовать это вместе:
class Demo:
# something with a 'value' method in it
def __init__(self, val):
self.value = val
def custom_enum(cls):
# class decorator to get __getattribute__() to work properly
# this is necessary because __getattribute__() only exists as an instance method,
# and there seems to be no direct equivalent for class methods
return cls()
@custom_enum
class E:
# first, define our enumerated variables in a dict
_enums = {
'A': Demo('a'),
'B': Demo('b'),
'chicken': Demo('cluck')
}
# then, override __getattribute__() to first get the key from the dict,
# and return the .value property of it
def __getattribute__(self, key):
# because of the decorator, we can't call self._enums or else we get a RecursionError
# therefore, we need to implicitly subclass `object`, and then
# deliberately invoke object.__getattribute__ on self, to access _enums
my_enums = object.__getattribute__(self, '_enums')
return my_enums[key].value
На самом деле определить значения вашего перечислимого так же просто, как редактировать _enums
dict. И как только вы это сделаете, все должно работать примерно так, как вы хотите:
>>> E.A
'a'
>>> E.B
'b'
>>> E.chicken
'cluck'
Отсюда вы можете изменить реализацию, если это необходимо (например, вернуть AttributeError
вместо KeyError
, например, или переопределить __setattr__()
, чтобы сделать значения enum не устанавливаемыми, или что-то еще).