Wie prüfe ich, ob ein Objekt von einem bestimmten Typ ist oder ob es von einem bestimmten Typ erbt?
Wie kann ich überprüfen, ob das Objekt o
ist vom Typ str
?
Wie prüfe ich, ob ein Objekt von einem bestimmten Typ ist oder ob es von einem bestimmten Typ erbt?
Wie kann ich überprüfen, ob das Objekt o
ist vom Typ str
?
Utilice isinstance
um zu prüfen, ob o
ist eine Instanz von str
oder einer Unterklasse von str
:
if isinstance(o, str):
Um zu prüfen, ob der Typ der o
ist genau str
, mit Ausnahme der Unterklassen von str
:
if type(o) is str:
Eine weitere Alternative zu den oben genannten Möglichkeiten:
if issubclass(type(o), str):
Ver Eingebaute Funktionen in der Python Library Reference für relevante Informationen.
Für Python 2 ist dies ein besserer Weg, um zu prüfen, ob o
ist eine Zeichenkette:
if isinstance(o, basestring):
weil dadurch auch Unicode-Zeichenfolgen erfasst werden. unicode
ist nicht eine Unterklasse von str
in der Erwägung, dass beide str
y unicode
sind Unterklassen von basestring
. In Python 3, basestring
nicht mehr existiert, da es eine eine strikte Trennung von Zeichenketten ( str
) und binäre Daten ( bytes
).
Alternativ dazu, isinstance
akzeptiert ein Tupel von Klassen. Dies wird zurückgegeben True
si o
eine Instanz einer beliebigen Unterklasse einer der folgenden Klassen ist (str, unicode)
:
if isinstance(o, (str, unicode)):
Str.__subclasses__() gibt nur die direkten Unterklassen von str zurück und tut nicht dasselbe wie issubclass() oder isinstance(). (Um das zu tun, müssten Sie rekursiv .__subclasses__() aufrufen.
Das ist eine gute Antwort, aber ich denke, sie sollte wirklich mit einer Warnung beginnen, dass Sie dies normalerweise nicht in Python tun sollten. So wie es ist, scheint es die Annahme zu bestätigen, dass dies eine "kanonische Sache in Python zu tun" ist, die es nicht ist.
Was ist der Unterschied zwischen "Instanz" und "genau"? Wenn type(a) is Object
ist es dann nicht auch wahr, dass isinstance(a, Object)
. Wenn jedoch type(a) is SubClassOfObject
dann type(a) is Object == False
pero isinstance(a, Object) == True
. Oder?
El Die meisten Der pythonische Weg, den Typ eines Objekts zu prüfen, ist... ihn nicht zu prüfen.
Da Python ermutigt Duck Typing sollten Sie einfach try...except
um die Methoden des Objekts so zu verwenden, wie Sie sie verwenden wollen. Wenn Ihre Funktion also nach einem beschreibbaren Dateiobjekt sucht, nicht prüfen, ob es sich um eine Unterklasse von file
versuchen Sie einfach, seine .write()
Methode!
Natürlich brechen diese schönen Abstraktionen manchmal zusammen und isinstance(obj, cls)
ist das, was Sie brauchen. Aber gehen Sie sparsam damit um.
Meiner Meinung nach ist der pythonischste Weg, mit jedem Argument zurechtzukommen, das gegeben wird. In meinem Code kann ich oft nicht wissen, ob ich ein Objekt oder ein Array von Objekten erhalte, und ich verwende intern eine Typüberprüfung, um ein einzelnes Objekt in eine Liste mit einem Element zu konvertieren.
Anstatt nur zu versuchen, seine Write-Methode zu verwenden, gibt es Zeiten, in denen Sie dies tun möchten, ohne eine Ausnahme zu verursachen. In diesem Fall könnten Sie tun... if hasattr(ob, "write") and callable(ob.write):
Oder sparen Sie sich den Zugang zu einem Diktat... func = getattr(ob, "write", None)
if callable(func): ...
Duck typing ist über mit eine Bibliothek. Bei der Typprüfung geht es um Schreiben eine Bibliothek. Nicht derselbe Problembereich.
Natürlich schlägt dies fehl, wenn das Objekt nicht eine Instanz von "str" ist, sondern von etwas, das einer Zeichenkette ähnelt. Wie Unicode, mmap, UserString oder ein anderer benutzerdefinierter Typ. Der übliche Ansatz in Python ist es, keine Typüberprüfungen durchzuführen.
En Python 3.10 können Sie verwenden |
en isinstance
:
>>> isinstance('1223', int | str)
True
>>> isinstance('abcd', int | str)
True
Nachdem die Frage gestellt und beantwortet wurde, Typ-Hinweise wurden zu Python hinzugefügt . Typhinweise in Python ermöglichen die Überprüfung von Typen, aber auf eine ganz andere Weise als bei statisch typisierten Sprachen. Typ-Hinweise in Python assoziieren die erwarteten Typen von Argumenten mit Funktionen als zur Laufzeit zugängliche Daten, die mit Funktionen verbunden sind, und dies ermöglicht für zu prüfende Typen. Beispiel für die Syntax eines Typhinweises:
def foo(i: int):
return i
foo(5)
foo('oops')
In diesem Fall soll ein Fehler ausgelöst werden bei foo('oops')
da der annotierte Typ des Arguments int
. Der hinzugefügte Typ-Hinweis bedeutet nicht verursachen ein Fehler auftritt, wenn das Skript normal ausgeführt wird. Es fügt der Funktion jedoch Attribute hinzu, die die erwarteten Typen beschreiben, die andere Programme abfragen und zur Prüfung auf Typfehler verwenden können.
Eines dieser anderen Programme, die zum Auffinden des Typfehlers verwendet werden können, ist mypy
:
mypy script.py
script.py:12: error: Argument 1 to "foo" has incompatible type "str"; expected "int"
(Möglicherweise müssen Sie die mypy
von Ihrem Paketmanager. Ich glaube nicht, dass es mit CPython kommt, aber scheint ein gewisses Maß an "Offizialität" zu haben).
Die Typüberprüfung auf diese Weise unterscheidet sich von der Typüberprüfung in statisch typisierten kompilierten Sprachen. Da die Typen in Python dynamisch sind, muss die Typprüfung zur Laufzeit durchgeführt werden, was Kosten verursacht - sogar für korrekte Programme - wenn wir darauf bestehen, dass dies bei jeder Gelegenheit geschieht. Explizite Typüberprüfungen können auch restriktiver sein als nötig und unnötige Fehler verursachen (z.B. muss das Argument wirklich genau list
Typs oder ist irgendetwas Iterierbares ausreichend?).
Der Vorteil der expliziten Typprüfung besteht darin, dass sie Fehler früher erkennen und klarere Fehlermeldungen ausgeben kann als die Duck-Typisierung. Die genauen Anforderungen eines Duck-Typs können nur mit externer Dokumentation ausgedrückt werden (die hoffentlich gründlich und genau ist), und Fehler aufgrund inkompatibler Typen können weit entfernt vom Ursprungsort auftreten.
Pythons Typ-Hinweise sollen einen Kompromiss bieten, bei dem Typen angegeben und überprüft werden können, aber keine zusätzlichen Kosten bei der normalen Codeausführung entstehen.
El typing
Paket bietet Typvariablen, die in Typhinweisen verwendet werden können, um benötigte Verhaltensweisen auszudrücken, ohne dass bestimmte Typen erforderlich sind. Zum Beispiel enthält es Variablen wie Iterable
y Callable
für Hinweise auf die Notwendigkeit eines Typs mit diesen Verhaltensweisen.
Während Typhinweise der pythonischste Weg sind, Typen zu prüfen, ist es oft noch pythonischer, Typen überhaupt nicht zu prüfen und sich auf Duck Typing zu verlassen. Typhinweise sind relativ neu, und es ist noch nicht klar, wann sie die beste pythonische Lösung sind. Ein relativ unumstrittener, aber sehr allgemeiner Vergleich: Typ-Hinweise bieten eine Form der Dokumentation, die erzwungen werden kann, ermöglichen es, dass Code früher und leichter zu verstehen Fehler generiert, können Fehler abfangen, die Duck-Typing nicht kann, und können statisch überprüft werden (in einem ungewöhnlichen Sinn, aber es ist immer noch außerhalb der Laufzeit). Auf der anderen Seite ist Duck-Typing seit langem der Weg von Pythonic, erzwingt nicht den kognitiven Overhead der statischen Typisierung, ist weniger langatmig und akzeptiert alle brauchbaren Typen und noch einige mehr.
-1: mypy bezeichnet sich ausdrücklich als "statische Typüberprüfung", daher bin ich mir nicht sicher, woher Sie die Aussage "Typüberprüfung muss zur Laufzeit erfolgen" haben.
@Kevin Im Nachhinein war das eine unnötige Abschweifung, aber um mehr darüber zu erfahren, werden Pythons Typ-Hinweise in Laufzeitdaten umgewandelt und mypy
ist ein Python-Modul, das die importlib
um auf diese Daten zuzugreifen. Ob dies eine "statische Typüberprüfung" ist, ist eine philosophische Frage, aber es ist anders als die meisten erwarten würden, da der normale Sprachinterpreter und die Importmaschinerie beteiligt sind.
Auch das ist nicht wahr. Es verwendet typed_ast, die selbst ist nur ein Klon von ast mit zusätzlichen Funktionen. ast importiert keine Module, sondern zerlegt sie in einen abstrakten Syntaxbaum.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
16 Stimmen
Ich glaube, Herr Coombs übersieht Beispiele wie nicht-JSON serialisierbare Klassen. Wenn man einen großen Datenblock durch eine Funktion schickt (deren Code man nicht beeinflussen kann), möchte man vielleicht bestimmte Teile dieser Daten in ein <str> konvertieren, bevor man sie weitergibt. Zumindest ist das so I landete auf dieser Seite...
7 Stimmen
Es scheint, dass der häufigste Grund für diese Frage darin besteht, dass man zwischen Zeichenketten und Iterablen von Zeichenketten unterscheiden möchte. Dies ist eine knifflige Frage, weil Strings sind Iterabilen von Zeichenketten - eine Ein-Zeichen-Zeichenkette ist sogar eine Folge von sich selbst (als ich das letzte Mal nachgesehen habe - man sollte sich wahrscheinlich nicht darauf verlassen). Aber würde jemand jemals Verwendung für etwas String-ähnliches haben? Oui . Die Antwort auf die Frage "Wie unterscheide ich zwischen Zeichenketten und anderen Iterabilen von Zeichenketten?" ist also richtig: "Das hängt davon ab, was Sie tun wollen" :-D
7 Stimmen
Python-Typ-Annotationen sind jetzt eine Sache. Werfen Sie einen Blick auf mypy