Python 3.6 steht kurz vor der Veröffentlichung. PEP 494 - Python 3.6 Release Schedule erwähnt Ende Dezember, daher habe ich die Neuerungen in Python 3.6 durchgesehen, um zu sehen, dass sie die variablen Anmerkungen erwähnen :
Mit PEP 484 wurde ein Standard für Typanmerkungen von Funktionsparametern eingeführt, auch bekannt als Typhinweise. Dieser PEP fügt Python eine Syntax zum Kommentieren der Variablentypen hinzu, einschließlich Klassenvariablen und Instanzvariablen:
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: Dict[str, int] = {}
Genau wie bei Funktionsanmerkungen misst der Python-Interpreter Variablenanmerkungen keine besondere Bedeutung bei und speichert sie nur in einem speziellen Attribut
__annotations__
einer Klasse oder eines Moduls. Im Gegensatz zu Variablendeklarationen in statisch typisierten Sprachen besteht das Ziel der Anmerkungssyntax darin, auf einfache Weise strukturierte Typmetadaten für Tools und Bibliotheken von Drittanbietern über den abstrakten Syntaxbaum und das__annotations__
Attribut anzugeben .
Also von dem, was ich lese sie sind Teil der Typ Hinweise von Python kommen 3.5, beschrieben in Was Typ Hinweise in Python sind 3.5 .
Ich folge dem Beispiel captain: str
und bin mir class Starship
aber nicht sicher, was das letzte angeht: Wie erklärt sich primes: List[int] = []
das? Definiert es eine leere Liste, die nur ganze Zahlen zulässt?
quelle
primes: List[int] = []
ist nur eine leere Liste alsprimes = []
. Der Unterschied ist , dass Sie behaupten , dassprimes
soll dich auf nur enthaltenint
s und 3rd - Party - Anwendungen möglicherweise geben Sie Ihr Programm überprüfen , diese Behauptung zu überprüfen, aber wenn Sie den Code in jedem Python - Interpreter ausführen , die genau das gleiche wie das Schreiben istprimes = []
, und so tun ,primes: List[int] = []; primes.append("string")
ist nach wie vor gültig.Antworten:
Alles zwischen
:
und=
ist ein Typhinweis, wird alsoprimes
tatsächlich als definiertList[int]
und zunächst auf eine leere Liste gesetzt (undstats
ist zunächst ein leeres Wörterbuch, definiert alsDict[str, int]
).List[int]
undDict[str, int]
sind nicht Teil der nächsten Syntax, diese wurden jedoch bereits in den Python 3.5-Tipphinweisen PEP definiert. Der Vorschlag 3.6 PEP 526 - Syntax für Variablenanmerkungen definiert nur die Syntax zum Anhängen derselben Hinweise an Variablen. zuvor konnten Sie Variablen mit Kommentaren (zprimes = [] # List[int]
. B. ) nur Typhinweise hinzufügen .Beide
List
undDict
sind generische Typen, die angeben, dass Sie eine Listen- oder Wörterbuchzuordnung mit bestimmten (konkreten) Inhalten haben.Denn
List
es gibt nur ein 'Argument' (die Elemente in der[...]
Syntax), den Typ jedes Elements in der Liste. FürDict
ist das erste Argument der Schlüssel - Typ und der zweite ist der Wert ein. Also alle Werte in derprimes
Liste ganze Zahlen sind, und alle Schlüssel-Wert - Paare imstats
Wörterbuch sind(str, int)
Paare, Strings auf ganze Zahlen abbildet.Siehe die
typing.List
undtyping.Dict
Definitionen, den Abschnitt über Generika sowie PEP 483 - The Theory of Type Hints .Wie Typhinweise zu Funktionen ist ihre Verwendung optional und wird auch als Annotation betrachtet (vorausgesetzt, es gibt ein Objekt, an das diese angehängt werden können, also Globale in Modulen und Attributen in Klassen, aber keine Einheimischen in Funktionen), die Sie über das
__annotations__
Attribut überprüfen können . Sie können diesen Anmerkungen beliebige Informationen hinzufügen. Sie sind nicht streng darauf beschränkt, Hinweisinformationen einzugeben.Vielleicht möchten Sie den vollständigen Vorschlag lesen . Es enthält einige zusätzliche Funktionen, die über die neue Syntax hinausgehen. Es gibt an, wann solche Annotationen ausgewertet werden, wie sie überprüft werden und wie beispielsweise etwas als Klassenattribut oder Instanzattribut deklariert wird.
quelle
obj.__annotations__
Attributs)?Variable Anmerkungen sind nur der nächste Schritt von
# type
Kommentaren, wie sie in definiert wurdenPEP 484
. Die Gründe für diese Änderung werden im jeweiligen Abschnitt von PEP 526 hervorgehoben .Anstatt den Typ mit folgenden Hinweisen zu versehen:
primes = [] # type: List[int]
Es wurde eine neue Syntax eingeführt , mit der der Typ direkt mit einer Zuweisung des Formulars versehen werden kann:
Dies bezeichnet, wie @Martijn hervorhob, eine Liste von Ganzzahlen, indem die in verfügbaren Typen verwendet
typing
und in eine leere Liste initialisiert werden.Die erste eingeführte Änderung war eine neue Syntax , mit der Sie einen Namen mit einem Typ versehen können, entweder eigenständig nach dem
:
Zeichen oder optional mit Anmerkungen versehen und ihm gleichzeitig einen Wert zuweisen können:annotated_assignment_stmt ::= augtarget ":" expression ["=" expression]
Also das fragliche Beispiel:
primes: List[int] = [ ] # ^ ^ ^ # augtarget | | # expression | # expression (optionally initialize to empty list)
Mit der neuen Syntax wurden auch zusätzliche Änderungen eingeführt. Module und Klassen haben jetzt ein
__annotations__
Attribut (wie es Funktionen seit PEP 3107 - Funktionsanmerkungen hatten ), an das die Typmetadaten angehängt sind:from typing import get_type_hints # grabs __annotations__
Nun
__main__.__annotations__
enthält die deklarierten Typen:>>> from typing import List, get_type_hints >>> primes: List[int] = [] >>> captain: str >>> import __main__ >>> get_type_hints(__main__) {'primes': typing.List<~T>[int]}
captain
wird derzeit nicht angezeigt,get_type_hints
daget_type_hints
nur Typen zurückgegeben werden, auf die auch in einem Modul zugegriffen werden kann. dh es braucht zuerst einen Wert:>>> captain = "Picard" >>> get_type_hints(__main__) {'primes': typing.List<~T>[int], 'captain': <class 'str'>}
Die Verwendung
print(__annotations__)
wird angezeigt,'captain': <class 'str'>
aber Sie sollten wirklich nicht__annotations__
direkt darauf zugreifen .Ebenso für Klassen:
>>> get_type_hints(Starship) ChainMap({'stats': typing.Dict<~KT, ~VT>[str, int]}, {})
Wobei a
ChainMap
verwendet wird, um die Annotationen für eine bestimmte Klasse (in der ersten Zuordnung) und alle Annotationen abzurufen, die in den Basisklassen definiert sind, die in ihrermro
Zuordnung gefunden wurden (nachfolgende Zuordnungen{}
für Objekt).Zusammen mit der neuen Syntax wurde ein neuer
ClassVar
Typ hinzugefügt, um Klassenvariablen zu kennzeichnen. Ja,stats
in Ihrem Beispiel handelt es sich tatsächlich um eine Instanzvariable , nicht um eineClassVar
.Wie bei Typhinweisen von
PEP 484
sind diese vollständig optional und werden hauptsächlich für Tools zur Typprüfung verwendet (und was auch immer Sie basierend auf diesen Informationen erstellen können). Es soll vorläufig sein, wenn die stabile Version von Python 3.6 veröffentlicht wird, damit in Zukunft möglicherweise kleine Änderungen hinzugefügt werden.quelle