Как проверить, существует ли строка в Enum of strings?

Я создал следующее Enum:

from enum import Enum class Action(str, Enum): NEW_CUSTOMER = "new_customer" LOGIN = "login" BLOCK = "block" 

Я тоже унаследовал 9X_object-oriented-design от str, поэтому могу делать такие вещи, как:

action = "new_customer" ... if action == Action.NEW_CUSTOMER: ... 

Теперь 9X_method-overriding я хотел бы иметь возможность проверить, находится 9X_pythonic ли строка в этом Enum, например:

if "new_customer" in Action: .... 

Я пробовал 9X_object-oriented-design добавить к классу следующий метод:

def __contains__(self, item): return item in [i for i in self] 

Однако, когда 9X_object-oriented-design я запускаю этот код:

print("new_customer" in [i for i in Action]) print("new_customer" in Action) 

Я получаю это исключение:

True Traceback (most recent call last): File "/Users/kevinobrien/Documents/Projects/crazywall/utils.py", line 24, in print("new_customer" in Action) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/enum.py", line 310, in __contains__ raise TypeError( TypeError: unsupported operand type(s) for 'in': 'str' and 'EnumMeta' 

16
1

  • Я снова открыл этот вопрос. Речь идет о строках ...
4
Общее количество ответов: 4

Ответ #1

Ответ на вопрос: Как проверить, существует ли строка в Enum of strings?

Я столкнулся с этой проблемой сегодня; Мне 9X_class пришлось изменить ряд подпакетов для Python 9X_enum 3.8.

Возможно, альтернативой другим решениям 9X_py здесь является следующее, вдохновленное 9X_python отличным ответом here на аналогичный вопрос, а 9X_python-shell также answer on this page @ MadPhysicist:

class MetaEnum(EnumMeta): def __contains__(cls, item): try: cls(item) except ValueError: return False return True class BaseEnum(Enum, metaclass=MetaEnum): pass class Stuff(BaseEnum): foo = 1 bar = 5 

Тесты (в py37 или 38):

>>> 1 in Stuff True >>> Stuff.foo in Stuff True >>> 2 in Stuff False >>> 2.3 in Stuff False >>> 'zero' in Stuff False 

17
0

Ответ #2

Ответ на вопрос: Как проверить, существует ли строка в Enum of strings?

Вы можете проверить, содержит ли перечисление 9X_classes значение, вызвав его:

>>> Action('new_customer') Action.NEW_CUSTOMER 

Если объект, который 9X_python-shell вы передаете, не гарантирует нахождение 9X_py в перечислении, вы можете использовать блок 9X_pythonic try для захвата результирующего ValueError. Например,

def is_action(obj): try: Action(obj) except ValueError: return False return True 

11
0

Ответ #3

Ответ на вопрос: Как проверить, существует ли строка в Enum of strings?

Учитывая перечисление языков

class Language(enum.Enum): en = 'en' zh = 'zh' @classmethod def has_member_key(cls, key): return key in cls.__members__ print(Language.has_member_key('tu')) => False print(Language.has_member_key('en')) => True 

9X_object-oriented

9
0

Ответ #4

Ответ на вопрос: Как проверить, существует ли строка в Enum of strings?

Поскольку Action является производным классом 9X_enums Enum, мы можем использовать тот факт, что 9X_overriding Enum имеет член с именем _value2member_map_.

value2member_map - это частный 9X_enum атрибут (т.е. внутри CPython), который сопоставляет 9X_enum значения с именами (хотя будет работать 9X_enums только для хешируемых значений). Однако 9X_oop полагаться на частные атрибуты - не лучший 9X_object-oriented-design вариант, поскольку их можно изменить в любое 9X_oop время.

Reference

Получаем следующее:

if "new_customer" in Action._value2member_map_: # works 

что близко к желаемому:

if "new_customer" in Action: # doesn't work (i.e. TypeError) 

3
0