Eine der am häufigsten diskutierten Funktionen in Python 3.5 sind Typhinweise .
Ein Beispiel für Typ Hinweise wird in erwähnt diesen Artikel und diese während auch Typ Hinweise verantwortungsvoll nutzen erwähnen. Kann jemand mehr über sie erklären und wann sie verwendet werden sollten und wann nicht?
python
python-3.x
python-3.5
type-hinting
Vaulstein
quelle
quelle
Antworten:
Ich würde vorschlagen, PEP 483 und PEP 484 zu lesen und diese Präsentation von Guido über Typhinweise anzusehen.
Kurz gesagt : Typhinweise sind wörtlich das, was die Wörter bedeuten. Sie geben den Typ der Objekte an, die Sie verwenden .
Aufgrund der Dynamik von Python ist es besonders schwierig , den Typ eines verwendeten Objekts abzuleiten oder zu überprüfen . Diese Tatsache macht es Entwicklern schwer zu verstehen, was genau in Code vor sich geht, den sie nicht geschrieben haben, und vor allem für Tools zur Typprüfung, die in vielen IDEs [PyCharm, PyDev] vorkommen, die aufgrund dieser Tatsache eingeschränkt sind Sie haben keinen Indikator für den Typ der Objekte. Infolgedessen versuchen sie, den Typ mit einer Erfolgsquote von etwa 50% (wie in der Präsentation erwähnt) abzuleiten.
So nehmen Sie zwei wichtige Folien aus der Präsentation "Typhinweis":
Warum Hinweise eingeben?
TypeErrors
..
Methoden und Attribute angezeigt wurden, die nicht für ein Objekt definiert sind.Warum statische Typprüfer verwenden?
Zum Abschluss dieser kleinen Einführung : Dies ist eine optionale Funktion, die meines Wissens eingeführt wurde, um einige der Vorteile der statischen Typisierung zu nutzen.
Sie müssen sich im Allgemeinen keine Sorgen machen und müssen es definitiv nicht verwenden (insbesondere in Fällen, in denen Sie Python als zusätzliche Skriptsprache verwenden). Dies sollte bei der Entwicklung großer Projekte hilfreich sein, da es die dringend benötigte Robustheit, Kontrolle und zusätzliche Debugging-Funktionen bietet .
Tippe mit mypy :
Um diese Antwort zu vervollständigen, halte ich eine kleine Demonstration für angebracht. Ich werde
mypy
die Bibliothek verwenden, die Type Hints inspiriert hat, wie sie im PEP präsentiert werden. Dies ist hauptsächlich für alle geschrieben, die auf diese Frage stoßen und sich fragen, wo sie anfangen sollen.Bevor ich das tue, möchte ich Folgendes wiederholen: PEP 484 erzwingt nichts; Es wird lediglich eine Richtung für Funktionsanmerkungen festgelegt und Richtlinien vorgeschlagen, wie die Typprüfung durchgeführt werden kann / sollte. Sie können Ihre Funktionen mit Anmerkungen versehen und so viele Dinge andeuten, wie Sie möchten. Ihre Skripte werden unabhängig vom Vorhandensein von Anmerkungen weiterhin ausgeführt, da Python sie selbst nicht verwendet.
Wie im PEP angegeben, sollten Andeutungstypen im Allgemeinen drei Formen annehmen:
# type: type
Kommentare, die die ersten beiden Formen ergänzen. (Siehe: Was sind variable Anmerkungen in Python 3.6? Für ein Python 3.6-Update für# type: type
Kommentare)Darüber hinaus möchten Sie Typhinweise in Verbindung mit dem in eingeführten neuen
typing
Modul verwendenPy3.5
. Darin werden viele (zusätzliche) ABCs (Abstract Base Classes) zusammen mit Hilfsfunktionen und Dekoratoren zur Verwendung bei der statischen Überprüfung definiert. Die meistenABCs
incollections.abc
sind enthalten, jedoch in einerGeneric
Form, um ein Abonnement zu ermöglichen (durch Definieren einer__getitem__()
Methode).Für alle, die an einer ausführlicheren Erklärung interessiert sind,
mypy documentation
ist das sehr schön geschrieben und enthält viele Codebeispiele, die die Funktionalität ihres Prüfers demonstrieren / beschreiben. Es ist definitiv eine Lektüre wert.Funktionsanmerkungen und spezielle Kommentare:
Zunächst ist es interessant, einige Verhaltensweisen zu beobachten, die bei Verwendung spezieller Kommentare auftreten können.
# type: type
Während der Variablenzuweisung können spezielle Kommentare hinzugefügt werden, um den Typ eines Objekts anzugeben, wenn einer nicht direkt abgeleitet werden kann. Einfache Zuordnungen lassen sich im Allgemeinen leicht ableiten, andere, wie Listen (in Bezug auf ihren Inhalt), jedoch nicht.Hinweis: Wenn wir eine Ableitung von verwenden möchten
Containers
und den Inhalt für diesen Container angeben müssen , müssen wir die generischen Typen aus demtyping
Modul verwenden. Diese unterstützen die Indizierung.Wenn wir diese Befehle zu einer Datei hinzufügen und sie mit unserem Interpreter ausführen, funktioniert alles einwandfrei und
print(a)
druckt nur den Inhalt der Listea
. Die# type
Kommentare wurden verworfen und als einfache Kommentare behandelt, die keine zusätzliche semantische Bedeutung haben .Wenn
mypy
wir dies mit ausführen, erhalten wir andererseits die folgende Antwort:Zeigt an, dass eine Liste von
str
Objekten keine enthalten kannint
, was statisch gesehen ein Ton ist. Dies kann behoben werden, indem entweder der Typ der Objektea
beibehalten und nur angehängt wirdstr
oder indem der Inhaltstyp vona
geändert wird, um anzuzeigen, dass ein beliebiger Wert akzeptabel ist (Intuitiv ausgeführt mitList[Any]
afterAny
, aus dem importiert wurdetyping
).Funktionsanmerkungen werden im Formular
param_name : type
nach jedem Parameter in Ihrer Funktionssignatur hinzugefügt, und ein Rückgabetyp wird unter Verwendung der-> type
Notation vor dem Endpunkt der Funktionsfunktion angegeben. Alle Anmerkungen werden im__annotations__
Attribut für diese Funktion in einer praktischen Wörterbuchform gespeichert . Verwenden eines einfachen Beispiels (für das keine zusätzlichen Typen aus demtyping
Modul erforderlich sind ):Das
annotated.__annotations__
Attribut hat jetzt die folgenden Werte:Wenn wir ein absoluter Noobie sind oder mit
Py2.7
Konzepten vertraut sind und daher dasTypeError
Lauern im Vergleich von nicht kennenannotated
, können wir eine weitere statische Überprüfung durchführen, den Fehler abfangen und uns einige Probleme ersparen:Unter anderem wird der Aufruf der Funktion mit ungültigen Argumenten auch abgefangen:
Diese können grundsätzlich auf jeden Anwendungsfall ausgedehnt werden, und die festgestellten Fehler gehen weiter als grundlegende Aufrufe und Operationen. Die Typen, nach denen Sie suchen können, sind sehr flexibel, und ich habe nur einen kleinen Einblick in ihr Potenzial gegeben. Ein Blick in das
typing
Modul, die PEPs oder diemypy
Dokumente gibt Ihnen einen umfassenderen Überblick über die angebotenen Funktionen.Stub-Dateien:
Stub-Dateien können in zwei verschiedenen Fällen verwendet werden, die sich nicht gegenseitig ausschließen:
Was Stub-Dateien (mit einer Erweiterung von
.pyi
) sind, ist eine kommentierte Schnittstelle des Moduls, das Sie erstellen / verwenden möchten. Sie enthalten die Signaturen der Funktionen, die Sie mit dem Hauptteil der verworfenen Funktionen überprüfen möchten. Um ein Gefühl dafür zu bekommen, geben Sie drei zufällige Funktionen in einem Modul mit dem Namenrandfunc.py
:Wir können eine Stub-Datei erstellen
randfunc.pyi
, in die wir einige Einschränkungen einfügen können, wenn wir dies wünschen. Der Nachteil ist, dass jemand, der die Quelle ohne den Stub betrachtet, diese Annotationshilfe nicht wirklich erhält, wenn er versucht zu verstehen, was wohin weitergegeben werden soll.Wie auch immer, die Struktur einer Stub-Datei ist ziemlich simpel: Fügen Sie alle Funktionsdefinitionen mit leeren Körpern (
pass
gefüllt) hinzu und geben Sie die Anmerkungen entsprechend Ihren Anforderungen an. Nehmen wir hier an, wir möchten nur mitint
Typen für unsere Container arbeiten.Die
combine
Funktion gibt einen Hinweis darauf, warum Sie möglicherweise Anmerkungen in einer anderen Datei verwenden möchten. Manchmal wird der Code unübersichtlich und die Lesbarkeit verringert (großes Nein-Nein für Python). Sie könnten natürlich Typ-Aliase verwenden, aber das verwirrt manchmal mehr als es hilft (verwenden Sie sie also mit Bedacht).Dies sollte Sie mit den Grundkonzepten von Type Hints in Python vertraut machen. Obwohl die verwendete Typprüfung bereits verwendet wurde,
mypy
sollten nach und nach weitere Popups angezeigt werden, einige intern in IDEs ( PyCharm ) und andere als Standard-Python-Module. Ich werde versuchen, zusätzliche Prüfer / verwandte Pakete in die folgende Liste aufzunehmen, wenn ich sie finde (oder wenn vorgeschlagen).Dame, die ich kenne :
Verwandte Pakete / Projekte :
Das
typeshed
Projekt ist tatsächlich einer der besten Orte, an denen Sie nachsehen können, wie Typhinweise in einem eigenen Projekt verwendet werden können. Nehmen wir als Beispiel die__init__
Dunder derCounter
Klasse in der entsprechenden.pyi
Datei:Wo
_T = TypeVar('_T')
wird verwendet, um generische Klassen zu definieren . Für dieCounter
Klasse können wir sehen, dass sie entweder keine Argumente in ihrem Initialisierer annehmen, eine einzelneMapping
von einem beliebigen Typ zu einerint
oder eineIterable
von einem beliebigen Typ nehmen kann.Beachten : Eine Sache, die ich vergessen habe zu erwähnen, war, dass das
typing
Modul vorläufig eingeführt wurde . Aus PEP 411 :Also nimm die Dinge hier mit einer Prise Salz; Ich bin mir nicht sicher, ob es in bedeutender Weise entfernt oder verändert wird, aber man kann es nie erfahren.
** Ein weiteres Thema insgesamt, aber gültig im Rahmen von Typhinweisen:
PEP 526
Syntax für Variablenanmerkungen ist ein Versuch,# type
Kommentare durch die Einführung einer neuen Syntax zu ersetzen , mit der Benutzer den Variablentyp in einfachenvarname: type
Anweisungen mit Anmerkungen versehen können .Siehe Was sind variable Anmerkungen in Python 3.6? , wie bereits erwähnt, für ein kleines Intro zu diesen.
quelle
Zu Jims ausführlicher Antwort hinzufügen:
Überprüfen Sie das
typing
Modul - dieses Modul unterstützt Typhinweise gemäß PEP 484 .Die folgende Funktion nimmt beispielsweise Werte vom Typ an
str
und gibt sie wie folgt zurück:Das
typing
Modul unterstützt außerdem:quelle
Das neu veröffentlichte PyCharm 5 unterstützt Typhinweise. In ihrem Blog-Beitrag darüber (siehe Python 3.5-Typhinweise in PyCharm 5 ) bieten sie eine großartige Erklärung, welche Typhinweise vorhanden sind und welche nicht sowie einige Beispiele und Abbildungen, wie Sie sie in Ihrem Code verwenden können.
Darüber hinaus wird es in Python 2.7 unterstützt, wie in diesem Kommentar erläutert :
quelle
Typhinweise sind eine neue Ergänzung zu einer dynamischen Sprache, in der die Leute jahrzehntelang so einfache Namenskonventionen wie Ungarisch schworen (Objektbezeichnung mit dem ersten Buchstaben b = Boolian, c = Zeichen, d = Wörterbuch, i = Ganzzahl, l = Liste, n = numerisch , s = string, t = tuple) wurden nicht benötigt, zu umständlich, aber jetzt haben wir entschieden, dass es viel zu schwierig ist, die Sprache (type ()) zum Erkennen von Objekten und unsere ausgefallenen IDEs zu verwenden Ich brauche Hilfe bei allem, was so kompliziert ist und dass dynamisch zugewiesene Objektwerte sie sowieso völlig unbrauchbar machen, während eine einfache Namenskonvention alles für jeden Entwickler auf einen Blick hätte lösen können.
quelle
Typhinweise dienen der Wartbarkeit und werden von Python nicht interpretiert. Im folgenden Code führt die Zeile
def add(self, ic:int)
erst in der nächstenreturn...
Zeile zu einem Fehler :quelle