Как проверить, существует ли член Enum с определенным именем?

Использование Python 3.4 Я хочу проверить, содержит ли класс Enum член с определенным именем.

Пример:

class Constants(Enum):
    One = 1
    Two = 2
    Three = 3

print(Constants['One'])
print(Constants['Four'])

дает:

Constants.One
  File "C:\Python34\lib\enum.py", line 258, in __getitem__
    return cls._member_map_[name]
KeyError: 'Four'

Я мог бы поймать KeyError и принять исключение как указание на существование, но, может быть, есть более элегантный способ?

Ответ 2

Я бы сказал, что это подпадает под EAFP (проще попросить прощения, чем разрешение), концепция, которая относительно уникальна для Python.

Легче просить прощения, чем разрешения. Этот общий стиль кодирования Python предполагает наличие допустимых ключей или атрибутов и исключение исключений, если предположение оказывается ложным. Этот чистый и быстрый стиль характеризуется наличием множества попыток и исключений. Этот метод контрастирует со стандартом LBYL, общим для многих других языков, таких как C.

Это контрастирует с LBYL (Посмотрите, прежде чем прыгать), что я думаю, что вы хотите, когда говорите, что ищете "более элегантный способ".

Посмотрите, прежде чем прыгать. Этот стиль кодирования явно проверяет предварительные условия перед выполнением вызовов или поисковых запросов. Этот стиль контрастирует с подходом EAFP и характеризуется наличием многих операторов if.

В многопоточной среде подход LBYL может подвергнуть риску появление состояния гонки между "взглядом" и "прыжком". Например, код, если ключ в сопоставлении: return mapping [key] может завершиться неудачей, если другой поток удаляет ключ из сопоставления после теста, но перед поиском. Эта проблема может быть решена с помощью блокировок или с использованием подхода EAFP.

Поэтому, основываясь на документации, на самом деле лучше использовать блоки try/except для вашей проблемы.

TL; DR

Используйте блоки try/except, чтобы поймать исключение KeyError.

Ответ 3

Можно использовать следующее, чтобы проверить, существует ли имя:

if any(x for x in Constants if x.name == "One"):
  # Exists
else:
  # Doesn't Exist

Используем x.value для проверки значения перечисления:

if any(x for x in Constants if x.value == 1):
  # Exists
else:
  # Doesn't Exist