Wie würden Sie überprüfen, ob eine Variable ein Wörterbuch in Python ist?
Dies ist eine ausgezeichnete Frage, aber es ist bedauerlich, dass die am besten bewertete Antwort mit einer schlechten Empfehlung führt type(obj) is dict.
(Beachten Sie, dass Sie auch keinen dictVariablennamen verwenden sollten - es ist der Name des eingebauten Objekts.)
Wenn Sie Code schreiben, der von anderen importiert und verwendet wird, gehen Sie nicht davon aus, dass sie das eingebaute Diktat direkt verwenden. Diese Annahme macht Ihren Code unflexibler und in diesem Fall leicht versteckte Fehler, die das Programm nicht fehlerhaft machen würden .
Ich empfehle dringend, aus Gründen der Korrektheit, Wartbarkeit und Flexibilität für zukünftige Benutzer niemals weniger flexible, unidiomatische Ausdrücke in Ihrem Code zu haben, wenn es flexiblere, idiomatische Ausdrücke gibt.
isist ein Test für die Objektidentität . Es unterstützt keine Vererbung, keine Abstraktion und keine Schnittstelle.
Daher werde ich verschiedene Optionen bereitstellen, die dies tun.
Unterstützende Vererbung:
Dies ist die erste Empfehlung , die ich machen würde, denn es ermöglicht es Benutzern , ihre eigene Unterklasse von dict zu versorgen, oder eine OrderedDict, defaultdictoder Counteraus den Sammlungen Modul:
if isinstance(any_object, dict):
Es gibt aber noch flexiblere Möglichkeiten.
Unterstützende Abstraktionen:
from collections.abc import Mapping
if isinstance(any_object, Mapping):
Auf diese Weise kann der Benutzer Ihres Codes eine eigene benutzerdefinierte Implementierung einer abstrakten Zuordnung verwenden, die auch eine Unterklasse von enthält dict, und dennoch das richtige Verhalten erhalten.
Verwenden Sie die Schnittstelle
Sie hören häufig den OOP-Rat "Programmieren auf eine Schnittstelle".
Diese Strategie nutzt Pythons Polymorphismus oder Ententypisierung.
Versuchen Sie also einfach, auf die Schnittstelle zuzugreifen und die spezifischen erwarteten Fehler ( AttributeErrorfalls es keine gibt .itemsund TypeErrorfalls sie itemsnicht aufrufbar sind) mit einem vernünftigen Fallback abzufangen - und jetzt gibt Ihnen jede Klasse, die diese Schnittstelle implementiert, ihre Elemente (Anmerkung .iteritems()ist in Python weg) 3):
try:
items = any_object.items()
except (AttributeError, TypeError):
non_items_behavior(any_object)
else: # no exception raised
for item in items: ...
Vielleicht denken Sie, dass die Verwendung von Enten-Typisierung zu weit geht, um zu viele Fehlalarme zuzulassen, und dies kann abhängig von Ihren Zielen für diesen Code der Fall sein.
Fazit
Nicht verwenden is, um Typen auf Standardkontrollfluss zu überprüfen. Verwenden Sie isinstance, berücksichtigen Sie Abstraktionen wie Mappingoder MutableMappingund vermeiden Sie die Typprüfung insgesamt, indem Sie die Schnittstelle direkt verwenden.