変数がPythonの辞書であるかどうかをどのように確認しますか?
これは素晴らしい質問ですが、最も賛成された回答が不十分な推奨でリードされているのは残念ですtype(obj) is dict
。
(dict
変数名としても使用しないでください-組み込みオブジェクトの名前です。)
他の人がインポートして使用するコードを記述している場合は、組み込みのdictを直接使用することを想定しないでください。この推定により、コードの柔軟性が失われ、この場合、プログラムにエラーを発生させない、簡単に隠れたバグが作成されます。 。
将来のユーザーの正確性、保守性、柔軟性の目的で、より柔軟で慣用的な式がある場合は、コード内で柔軟性が低く、慣用的な式を使用しないことを強くお勧めします。
is
オブジェクトの同一性のテストです。継承、抽象化、インターフェースはサポートしていません。
だから私はいくつかのオプションを提供します。
継承のサポート:
それは、ユーザーが辞書の独自のサブクラスを供給することができるため、またはこれは、私がなるだろう最初の勧告であるOrderedDict
、defaultdict
またはCounter
コレクションモジュールから:
if isinstance(any_object, dict):
しかし、さらに柔軟なオプションがあります。
抽象化のサポート:
from collections.abc import Mapping
if isinstance(any_object, Mapping):
これにより、コードのユーザーは、抽象マッピングの独自のカスタム実装を使用できます。これには、のサブクラスも含まれdict
、正しい動作が得られます。
インターフェースを使用する
OOPのアドバイスである「インターフェイスへのプログラム」をよく耳にします。
この戦略は、Pythonのポリモーフィズムまたはダックタイピングを利用します。
だから、特定の期待のエラーをキャッチし、インターフェイスにアクセスしようとする(AttributeError
場合に何もありません.items
し、TypeError
場合にitems
呼び出すことはできません)合理的な代替と-そして、今実装は、インターフェースはあなたにその項目を(ノートが与えることをことを、任意のクラス.iteritems()
のPythonでなくなっています3):
try:
items = any_object.items()
except (AttributeError, TypeError):
non_items_behavior(any_object)
else: # no exception raised
for item in items: ...
おそらく、このようにダックタイピングを使用すると、誤検出が多すぎて許容できなくなる可能性があり、このコードの目的によっては、そうなる可能性があります。
結論
is
標準の制御フローのタイプをチェックするために使用しないでください。を使用しisinstance
、Mapping
またはのような抽象化MutableMapping
を検討し、インターフェースを直接使用して、型チェックを完全に回避することを検討してください。