web-dev-qa-db-ja.com

特定の名前の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をキャッチし、例外を存在の兆候と見なすことができますが、もっとエレガントな方法があるのでしょうか?

20
Trilarion

Enum.__members__- 名前をメンバーにマッピングする順序付けされた辞書

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

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

これは [〜#〜] eafp [〜#〜] (許可よりも許しを求める方が簡単)という、Pythonに比較的独特な概念に該当します。

許可より許しを求める方が簡単です。この一般的なPythonコーディングスタイルは、有効なキーまたは属性の存在を想定し、想定が偽であることが判明した場合に例外をキャッチします。このクリーンで高速なスタイルは、多数のtryおよびexceptステートメントの存在によって特徴付けられます。テクニックCなどの他の多くの言語に共通のLBYLスタイルとは対照的です。

これは [〜#〜] lbyl [〜#〜] (跳躍する前に見る)とは対照的です。これは、「よりエレガントな方法」を探していると私が思っていることです。

石橋を叩いて渡る。このコーディングスタイルは、呼び出しまたはルックアップを行う前に、事前条件を明示的にテストします。このスタイルはEAFPアプローチと対照的であり、ifステートメントが多数存在することが特徴です。

マルチスレッド環境では、LBYLアプローチは「見た目」と「跳躍」の間に競合状態を導入する危険を冒す可能性があります。たとえば、コードがマッピング内のキーの場合:return mapping [key]は、テスト後、ルックアップの前に別のスレッドがマッピングからキーを削除すると失敗する可能性があります。この問題は、ロックを使用するか、EAFPアプローチを使用することで解決できます。

したがって、ドキュメントに基づいて、実際にはtry/exceptブロックを使用して問題を解決することをお勧めします。

TL; DR

try例外をキャッチするには、except/KeyErrorブロックを使用します。

22
pzp

次を使用して、名前が存在するかどうかをテストできます。

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
5
paultop6