web-dev-qa-db-fra.com

Comment tester si un membre Enum avec un certain nom existe?

Utilisation de Python 3.4 Je veux tester si une classe Enum contient un membre avec un certain nom.

Exemple:

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

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

donne:

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

Je pourrais attraper le KeyError et prendre l'exception comme indication d'existence mais peut-être y a-t-il une manière plus élégante?

20
Trilarion

Vous pouvez utiliser Enum.__members__ - un dictionnaire ordonné mappant les noms aux membres :

In [12]: 'One' in Constants.__members__
Out[12]: True

In [13]: 'Four' in Constants.__members__
Out[13]: False
38
vaultah

Je dirais que cela relève de EAFP (Plus facile de demander pardon que permission), un concept qui est relativement unique à Python.

Plus facile de demander pardon que la permission. Ce style de codage commun Python suppose l'existence de clés ou d'attributs valides et intercepte les exceptions si l'hypothèse se révèle fausse. Ce style propre et rapide se caractérise par la présence de nombreuses instructions try et except. La technique contraste avec le style LBYL commun à de nombreuses autres langues comme le C.

Cela contraste avec LBYL (Regardez avant de sauter), c'est ce que je pense que vous voulez quand vous dites que vous recherchez "une manière plus élégante".

Réfléchir avant d'agir. Ce style de codage teste explicitement les conditions préalables avant d'effectuer des appels ou des recherches. Ce style contraste avec l'approche EAFP et se caractérise par la présence de nombreuses déclarations if.

Dans un environnement multi-thread, l'approche LBYL peut risquer d'introduire une condition de concurrence entre "le regard" et "le saut". Par exemple, le code, si clé dans le mappage: le mappage de retour [clé] peut échouer si un autre thread supprime la clé du mappage après le test, mais avant la recherche. Ce problème peut être résolu avec des verrous ou en utilisant l'approche EAFP.

Par conséquent, sur la base de la documentation, il est préférable d'utiliser des blocs try/except pour votre problème.

TL; DR

Utilisez les blocs try/except pour intercepter l'exception KeyError.

22
pzp

Pourrait utiliser les éléments suivants pour tester si le nom existe:

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

Utilisez x.value pour tester la valeur enum:

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