auf Werte prüfen
Variante 1
Beachten Sie, dass ein Enum
Mitglied aufgerufen wird _value2member_map_
(das nicht dokumentiert ist und in zukünftigen Python-Versionen geändert / entfernt werden kann):
print(Fruit._value2member_map_)
Sie können anhand Enum
dieser Karte testen, ob sich ein Wert in Ihrem befindet :
5 in Fruit._value2member_map_
7 in Fruit._value2member_map_
Variante 2
Wenn Sie sich nicht auf diese Funktion verlassen möchten, ist dies eine Alternative:
values = [item.value for item in Fruit]
oder (wahrscheinlich besser): benutze a set
; Der in
Bediener wird effizienter:
values = set(item.value for item in Fruit)
dann testen mit
5 in values
7 in values
füge has_value
deiner Klasse hinzu
Sie können dies dann als Methode zu Ihrer Klasse hinzufügen:
class Fruit(Enum):
Apple = 4
Orange = 5
Pear = 6
@classmethod
def has_value(cls, value):
return value in cls._value2member_map_
print(Fruit.has_value(5))
print(Fruit.has_value(7))
Test auf Schlüssel
Wenn Sie nach den Namen (und nicht nach den Werten) testen möchten, würde ich Folgendes verwenden _member_names_
:
'Apple' in Fruit._member_names_
'Mango' in Fruit._member_names_
HTTPStatus
Aufzählung aus der Standardbibliothek, die ab sofort 57 Einträge enthält. Ich würde niemals eine ganze Liste von Werten aus einer Aufzählung verarbeiten, und das Zwischenspeichern dieser Werte möchte ich vermeiden.set
für die Suche erstellen . das würde etwas zusätzlichen Speicherreturn any(value == item.value[0] for item in cls)
bei Python3 die Enum-Struktur ändern?Sie könnten verwenden
Enum.__members__
- ein geordnetes Wörterbuch, das den Mitgliedern Namen zuordnet :In [12]: 'Apple' in Fruit.__members__ Out[12]: True In [13]: 'Grape' in Fruit.__members__ Out[13]: False
quelle
Aufbauend auf dem, was Reda Maachi begonnen hat:
6 in Fruit.__members__.values()
gibt True zurück
7 in Fruit.__members__.values()
gibt False zurück
quelle
>>> Fruit.Orange in Fruit.__members__.values() True
Überprüfen Sie einfach, ob es in ist
Enum. _value2member_map_
In[15]: Fruit._value2member_map_ Out[15]: {4: <Fruit.Apple: 4>, 5: <Fruit.Orange: 5>, 6: <Fruit.Pear: 6>} In[16]: 6 in Fruit._value2member_map_ Out[16]: True In[17]: 7 in Fruit._value2member_map_ Out[17]: False
quelle
_value2member_map_
ist eine undokumentierte Funktion, daher ist es am besten, sie nicht zu verwenden.Sie können ein
__members__
spezielles Attribut verwenden , um Mitglieder zu durchlaufen:from enum import Enum class Fruit(Enum): Apple = 4 Orange = 5 Pear = 6 @staticmethod def has_value(item): return item in [v.value for v in Connection.__members__.values()]
quelle
Es gibt eine Möglichkeit, dass alle Aufzählungen überprüfen können, ob ein Element vorhanden ist:
import enum class MyEnumMeta(enum.EnumMeta): def __contains__(cls, item): return item in [v.value for v in cls.__members__.values()] class MyEnum(enum.Enum, metaclass=MyEnumMeta): FOO = "foo" BAR = "bar"
Jetzt können Sie eine einfache Überprüfung durchführen:
>>> "foo" in MyEnum True
Es kann sogar einfacher gemacht werden, wenn alle Werte der Aufzählung immer vom gleichen Typ sind - zum Beispiel Zeichenfolgen:
import enum class MyEnumMeta(enum.EnumMeta): def __contains__(cls, item): return item in cls.__members__.values() class MyEnum(str, enum.Enum, metaclass=MyEnumMeta): FOO = "foo" BAR = "bar"
quelle
Es gibt noch eine andere Einzeiler-Lösung, die noch niemand erwähnt hat:
is_value_in_fruit = any(f.value == value_to_check for f in Fruit)
Wenn Sie
IntEnum
anstelle vonEnum
(class Fruit(IntEnum)
) verwenden, können Sie dies auch einfach tunis_value_in_fruit = any(f == value_to_check for f in Fruit)
quelle
Wenn die Aufzählung viele Mitglieder hat, kann dieser Ansatz schneller sein, da keine neue Liste erstellt wird und die Aufzählung nicht mehr durchlaufen wird, wenn der angegebene Wert gefunden wurde:
any(x.value == 5 for x in Fruit) # True any(x.value == 7 for x in Fruit) # False
quelle
Tu es nicht.
Wenn Sie Enum verwenden, können Sie mit auf Enum testen
if isinstance(key, Fruit):
Aber ansonsten versuchen Sie .. ist die pythonische Methode, um auf Enum zu testen. In der Tat für jeden Bruch im Paradigma der Ententypisierung.
Die richtige und pythonische Methode zum Testen eines Int in einem IntEnum besteht darin, es auszuprobieren und einen ValueError abzufangen, wenn ein Fehler auftritt.
Viele der oben vorgeschlagenen Lösungen sind aktiv veraltet und werden von 3.8 nicht mehr zugelassen ("DeprecationWarning: Die Verwendung von Nicht-Enums bei Containment-Prüfungen führt zu TypeError in Python 3.8").
Wenn Sie wirklich nicht daran interessiert sind, Ihren Code modern zu halten, können Sie ihn einfach verwenden
if key in Fruit:
quelle
IntEnum
+__members__
Sie können das erforderliche Verhalten verwenden
IntEnum
und__members__
erreichen:from enum import IntEnum class Fruit(IntEnum): Apple = 4 Orange = 5 Pear = 6 >>> 6 in Fruit.__members__.values() True >>> 7 in Fruit.__members__.values() False
Enum
+ Listenverständnis +.value
Wenn Sie bleiben müssen / wollen
Enum
, können Sie Folgendes tun:>>> 6 in [f.value for f in Fruit] True >>> 7 in [f.value for f in Fruit] False
EAPF +
ValueError
Oder Sie können leichter um Vergebung bitten als um die Erlaubnismethode :
try: Fruit(x) except ValueError: return False else: return True
quelle
Eine EAFP- Version der Antwort:
try: Fruit(val) return True except ValueError: return False
quelle