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
?
Hier ist ein Beispiel dafür, warum das Tippen von Enten böse ist, ohne zu wissen, wann es gefährlich ist.
Zum Beispiel: Hier ist der Python-Code (möglicherweise unter Auslassung der korrekten Einrückung), beachten Sie, dass diese Situation vermeidbar ist, indem Sie sich um die Funktionen isinstance und issubclassof kümmern, um sicherzustellen, dass Sie, wenn Sie wirklich eine Ente brauchen, keine Bombe bekommen.
class Bomb:
def talk(self):
self.explode()
def explode(self):
print("BOOM!, The bomb explodes.")
class Duck:
def talk(self):
print("I am a duck, I will not blow up if you ask me to talk.")
class Kid:
kids_duck = None
def __init__(self):
print("Kid comes around a corner and asks you for money so he could buy a duck.")
def take_duck(self, duck):
self.kids_duck = duck
print("The kid accepts the duck, and happily skips along.")
def do_your_thing(self):
print("The kid tries to get the duck to talk.")
self.kids_duck.talk()
my_kid = Kid()
my_kid.take_duck(Bomb())
my_kid.do_your_thing()
HINWEIS: Das Beispiel ist alt und naiv, und die Gefahr ist stark übertrieben. Es wird als Proof of Concept ohne größere Änderungen außer der Aktualisierung auf Python 3 belassen. Ich weiß nicht mehr, was mich ursprünglich dazu veranlasst hat, dies zu schreiben.
Bomben können nicht sprechen. Fügen Sie keine unsinnigen Methoden hinzu, dann wird das nicht passieren.
@Dmitry, das ist die gängige Kritik am Duck Typing: de.wikipedia.org/wiki/Duck_typing#Kritik ... Sie sagen im Grunde, dass jede Schnittstelle, für die die Semantik nicht durch die Sprache erzwungen wird, böse ist. Ich glaube, das ist eher der Ansatz von Java. Der ganze Sinn von Pythons Duck-Typing ist, dass es nur funktioniert, wenn es eine allgemein gültige Konvention darüber gibt, was bestimmte Schnittstellen bedeuten. Zum Beispiel könnte man eine Menge Python-Code durch Überschreiben der __file__
Attribut (das üblicherweise verwendet wird, um dateiähnliche Objekte zu identifizieren) etwas anderes bedeuten.
Das Ganze läuft auf den alten Witz hinaus: "Herr Doktor, es tut weh, wenn ich das mache". ... "Dann tun Sie das nicht.". Unbefriedigend für jemanden, der an "wenn es kompiliert, läuft es" gewöhnt ist, aber das ist der Grund, warum die Testbesessenheit aus der Welt der dynamischen Sprachen herausgewachsen ist.
Für komplexere Typprüfungen mag ich Schreibschutz Ansatz der Validierung auf der Grundlage von Python-Typ-Hinweis-Annotationen:
from typeguard import check_type
from typing import List
try:
check_type('mylist', [1, 2], List[int])
except TypeError as e:
print(e)
Sie können sehr komplexe Validierungen auf sehr saubere und lesbare Weise durchführen.
check_type('foo', [1, 3.14], List[Union[int, float]])
# vs
isinstance(foo, list) and all(isinstance(a, (int, float)) for a in foo)
Ich denke, das Schöne an einer dynamischen Sprache wie Python ist, dass man so etwas eigentlich nicht überprüfen muss.
Ich würde einfach die erforderlichen Methoden für Ihr Objekt aufrufen und eine AttributeError
. Später können Sie dann Ihre Methoden mit anderen (scheinbar nicht verwandten) Objekten aufrufen, um verschiedene Aufgaben zu erfüllen, z. B. ein Objekt zum Testen zu spotten.
Ich habe dies oft verwendet, wenn ich Daten aus dem Internet mit urllib2.urlopen()
die eine Datei wie Objekt. Dieses kann wiederum an fast jede Methode übergeben werden, die aus einer Datei liest, da es die gleiche read()
Methode als eine echte Datei.
Aber ich bin sicher, dass es eine Zeit und einen Ort für die Verwendung von isinstance()
sonst wäre es wahrscheinlich nicht da :)
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