Не используйте класс enum, если вы хотите отобразить атрибуты в строки.Весь пункт модуля enum
предназначен для создания набора одноэлементных объектов, которые представляют перечисление, а не строки.Из документации модуля:
Перечисление - это набор символических имен (членов), привязанных к уникальным постоянным значениям .В пределах перечисления члены могут сравниваться по тождеству , а само перечисление может повторяться.)
выделение жирным шрифтом. Строки не являютсяуникальные постоянные значения (я могу создать больше "Fido"
строк по желанию) и не предназначены для сравнения по тождеству (хотя иногда для подмножества строк можно ).
Просто определите свой собственный класс с атрибутами, которые являются строками, напрямую:
class Pets:
DOG = "Fido"
CAT = "Kitty"
Ваша бесконечная ошибка рекурсии вызвана недопониманием с вашей стороны относительно того, для чего используется этот метод.Подобно всем специальным методам , object.attr
ищет __getattr__
для типа объекта , что означает здесь, что ваш метод применяется к экземплярам вашего Enum
подклассаатрибуты DOG
и CAT
здесь, а не к самому классу, и мешают метаклассу EnumMeta
, пытающемуся проверить атрибут _value_
, который обрабатывается вашим методом __getattr__
с использованием self
только что созданный экземпляр Pets.DOG
и item
установлены в '_value_'
, который затем вызывает getattr(Pets.DOG, '_value_')
, что вызывает __getattr__
и т. д.
Для вашего подхода к работе вам потребуетсядля подкласса EnumMeta
и реализации __getattribute__
на этом подклассе (__getattr__
когда-либо вызывается только для отсутствующих атрибутов).Однако учтите, что __getattribute__
используется для доступа к атрибуту all , поэтому вам необходимо сначала проверить наличие экземпляров текущего класса:
class EnumDirectValueMeta(EnumMeta):
def __getattribute__(cls, name):
value = super().__getattribute__(name)
if isinstance(value, cls):
value = value.value
return value
class Pets(Enum, metaclass=EnumDirectValueMeta):
DOG = "Fido"
CAT = "Kitty"
в этот моментPets.DOG
производит 'Fido'
.