und - Was ist die kanonische Methode, um in Python nach Typ zu suchen?




python punkte plotten (6)

Was ist der beste Weg zu überprüfen, ob ein bestimmtes Objekt einen bestimmten Typ hat? Wie wäre es mit der Überprüfung, ob das Objekt von einem bestimmten Typ erbt?

Sagen wir, ich habe ein Objekt o . Wie überprüfe ich, ob es ein str ?


Die pythonischste Art, den Typ eines Objekts zu überprüfen, ist ... es nicht zu überprüfen.

Da Python Duck Typing ermutigt, sollten Sie einfach versuchen, die Methoden des Objekts so zu verwenden, wie Sie sie verwenden möchten. Wenn Ihre Funktion nach einem beschreibbaren .write() sucht, prüfen Sie nicht , ob es sich um eine Unterklasse der file , versuchen Sie einfach ihre .write() -Methode zu verwenden!

Natürlich, manchmal diese schönen Abstraktionen brechen und isinstance(obj, cls) ist, was Sie brauchen. Aber sparsam.


Hier ist ein Beispiel, warum Ente tippen ist böse, ohne zu wissen, wann es gefährlich ist. Zum Beispiel: Hier ist der Python-Code (möglicherweise unter Auslassung der richtigen Einrückung), beachten Sie, dass diese Situation vermeidbar ist, indem Sie z. B. aufInstance und issubclassof Funktionen achten, um sicherzustellen, dass Sie keine Bombe bekommen, wenn Sie wirklich eine Ente benötigen.

class Bomb:
    def __init__(self):
        ""

    def talk(self):
        self.explode()

    def explode(self):
        print "BOOM!, The bomb explodes."

class Duck:
    def __init__(self):
        ""
    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 takeDuck(self, duck):
        self.kids_duck = duck
        print "The kid accepts the duck, and happily skips along"

    def doYourThing(self):
        print "The kid tries to get the duck to talk"
        self.kids_duck.talk()

myKid = Kid()
myBomb = Bomb()
myKid.takeDuck(myBomb)
myKid.doYourThing()

Nachdem die Frage gestellt und beantwortet wurde, wurden Typhinweise zu Python hinzugefügt . Typhinweise in Python ermöglichen die Überprüfung von Typen, jedoch auf eine ganz andere Art als bei statisch typisierten Sprachen. Typhinweisen in Python ordnen die erwarteten Typen von Argumenten Funktionen als mit Laufzeitfunktionen zugängliche Daten zu, die Funktionen zugeordnet sind, und ermöglicht die Überprüfung von Typen. Beispiel für eine Typhinweis-Syntax:

def foo(i: int):
    return i

foo(5)
foo('oops')

In diesem Fall möchten wir, dass ein Fehler für foo('oops') ausgelöst wird foo('oops') da der annotierte Typ des Arguments int . Der hinzugefügte Typhinweis verursacht keinen Fehler, wenn das Skript normal ausgeführt wird. Es fügt jedoch Attribute zu der Funktion hinzu, die die erwarteten Typen beschreibt, die andere Programme abfragen und verwenden können, um nach Typfehlern zu suchen.

Eines dieser anderen Programme, die verwendet werden können, um den mypy zu finden, ist mypy :

mypy script.py
script.py:12: error: Argument 1 to "foo" has incompatible type "str"; expected "int"

(Möglicherweise müssen Sie mypy von Ihrem Paket-Manager installieren. Ich glaube nicht, dass es mit CPython kommt, aber es scheint ein gewisses Maß an " mypy " zu haben.)

Die Typüberprüfung unterscheidet sich von der Typüberprüfung in statisch typisierten kompilierten Sprachen. Da Typen in Python dynamisch sind, muss die Typprüfung zur Laufzeit durchgeführt werden, was selbst bei korrekten Programmen Kosten verursacht, wenn wir darauf bestehen, dass dies bei jeder Gelegenheit geschieht. Explizite Typprüfungen können auch restriktiver als nötig sein und unnötige Fehler verursachen (zB muss das Argument wirklich vom Listentyp sein oder ist alles iterierbar genug?).

Der Vorteil der expliziten Typprüfung besteht darin, dass sie früher Fehler erkennen und deutlichere Fehlermeldungen ausgeben kann als die Duck-Typisierung. Die genauen Anforderungen eines Ducktyps können nur mit einer externen Dokumentation ausgedrückt werden (hoffentlich ist sie gründlich und genau) und Fehler von inkompatiblen Typen können weit entfernt von ihrem Ursprung auftreten.

Pythons Type-Hinweise sollen einen Kompromiss darstellen, bei dem Typen spezifiziert und überprüft werden können, aber es gibt keine zusätzlichen Kosten während der üblichen Code-Ausführung.

Das typing bietet Typvariablen, die in Typhinweisen verwendet werden können, um das erforderliche Verhalten auszudrücken, ohne dass bestimmte Typen erforderlich sind. Zum Beispiel enthält es Variablen wie Iterable und Callable für Hinweise, um die Notwendigkeit eines beliebigen Typs mit diesen Verhaltensweisen anzugeben.

Während Typhinweise die pythischste Art sind, Typen zu überprüfen, ist es oft noch mehr Pythonic, überhaupt keine Typen zu überprüfen und sich auf die Eingabe von Enten zu verlassen. Typhinweise sind relativ neu und die Jury ist immer noch am Ende, wenn sie die pythonischste Lösung ist. Ein relativ unumstrittener, aber sehr allgemeiner Vergleich: Typhinweise bieten eine Form von Dokumentation, die durchgesetzt werden kann, Code ermöglicht, frühere und leichter zu verstehende Fehler zu generieren, Fehler zu erfassen, die bei der Tippeingabe nicht möglich sind, und statisch (in einer ungewöhnlichen Sinn, aber es ist immer noch außerhalb der Laufzeit). Auf der anderen Seite ist die Enten-Typisierung für lange Zeit die pythonische Methode, sie stellt den kognitiven Overhead der statischen Typisierung nicht auf, ist weniger ausführlich und akzeptiert alle lebensfähigen Typen und dann einige.


Sie können anhand der folgenden Zeile prüfen, welcher Zeichentyp der angegebene Wert ist:

def chr_type(chrx):
    if chrx.isalpha()==True:
        return 'alpha'
    elif chrx.isdigit()==True:
        return 'numeric'
    else:
        return 'nothing'

chr_type("12)

Zu Hugo:

Sie meinen wahrscheinlich eher list als array , aber das deutet auf das ganze Problem mit der Typprüfung hin - Sie wollen nicht wissen, ob das fragliche Objekt eine Liste ist, Sie wollen wissen, ob es eine Art Sequenz ist oder ob es eine einzelne ist Objekt. Also versuche es wie eine Sequenz zu benutzen.

Angenommen, Sie möchten das Objekt zu einer vorhandenen Sequenz hinzufügen oder wenn es sich um eine Sequenz von Objekten handelt, fügen Sie alle Objekte hinzu

try:
   my_sequence.extend(o)
except TypeError:
  my_sequence.append(o)

Ein Trick dabei ist, wenn Sie mit Strings und / oder Sequenzen von Strings arbeiten - das ist knifflig, da ein String oft als einzelnes Objekt betrachtet wird, aber auch eine Folge von Zeichen. Schlimmer als das, da es sich wirklich um eine Folge von Einzellängen handelt.

Normalerweise entscheide ich mich dafür, meine API so zu gestalten, dass sie nur einen einzelnen Wert oder eine Sequenz akzeptiert - das macht die Dinge einfacher. Es ist nicht schwer, einen [ ] um Ihren einzelnen Wert herum zu legen, wenn Sie ihn übergeben.

(Dies kann jedoch zu Fehlern bei Strings führen, da sie wie Sequenzen aussehen.)


isinstance(o, str) gibt true wenn o eine str oder ein Typ ist, der von str erbt.

type(o) is str wird true dann true wenn o ein str ist. Es wird false wenn o von einem Typ ist, der von str erbt. ----





types