Die anderen Antworten haben gute Arbeit geleistet, um das Tippen von Enten und die einfache Antwort von tzot zu erklären :
Python hat keine Variablen wie andere Sprachen, in denen Variablen einen Typ und einen Wert haben. Es hat Namen, die auf Objekte verweisen, die ihren Typ kennen.
Eine interessante Sache hat sich jedoch seit 2010 (als die Frage zum ersten Mal gestellt wurde) geändert, nämlich die Implementierung von PEP 3107 (implementiert in Python 3). Sie können jetzt den Typ eines Parameters und den Typ des Rückgabetyps einer Funktion wie folgt angeben:
def pick(l: list, index: int) -> int:
return l[index]
Wir können hier sehen, dass pick
2 Parameter, eine Liste l
und eine Ganzzahl, benötigt werden index
. Es sollte auch eine Ganzzahl zurückgeben.
Hier wird also impliziert, dass l
es sich um eine Liste von Ganzzahlen handelt, die wir ohne großen Aufwand sehen können. Bei komplexeren Funktionen kann es jedoch etwas verwirrend sein, was die Liste enthalten soll. Wir möchten auch, dass der Standardwert index
0 ist. Um dies zu lösen, können Sie pick
stattdessen wie folgt schreiben :
def pick(l: "list of ints", index: int = 0) -> int:
return l[index]
Beachten Sie, dass wir jetzt einen String als Typ eingeben l
, der syntaktisch zulässig ist, aber nicht für das programmgesteuerte Parsen geeignet ist (worauf wir später zurückkommen werden).
Es ist wichtig zu beachten, dass Python kein a erhöht, TypeError
wenn Sie einen Float übergeben index
. Der Grund dafür ist einer der Hauptpunkte in Pythons Designphilosophie: "Wir sind alle einverstanden, dass Erwachsene hier sind" , was bedeutet, dass Sie dies erwarten Seien Sie sich bewusst, was Sie an eine Funktion übergeben können und was nicht. Wenn Sie wirklich Code schreiben möchten, der TypeErrors auslöst, können Sie mit der isinstance
Funktion überprüfen, ob das übergebene Argument vom richtigen Typ oder einer Unterklasse davon wie folgt ist:
def pick(l: list, index: int = 0) -> int:
if not isinstance(l, list):
raise TypeError
return l[index]
Mehr darüber, warum Sie dies selten tun sollten und was Sie stattdessen tun sollten, wird im nächsten Abschnitt und in den Kommentaren besprochen.
PEP 3107 verbessert nicht nur die Lesbarkeit des Codes, sondern verfügt auch über mehrere passende Anwendungsfälle, über die Sie hier lesen können .
Die Typanmerkung hat in Python 3.5 mit der Einführung von PEP 484, das ein Standardmodul für Typhinweise einführt, viel mehr Aufmerksamkeit erhalten .
Diese Typhinweise stammen vom Typprüfer mypy ( GitHub ), der jetzt PEP 484- kompatibel ist.
Das Schreibmodul enthält eine ziemlich umfassende Sammlung von Tipphinweisen, darunter:
List
, Tuple
, Set
, Map
- für list
, tuple
, set
und map
jeweils.
Iterable
- nützlich für Generatoren.
Any
- wenn es irgendetwas sein könnte.
Union
- wenn es sich um etwas innerhalb eines bestimmten Satzes von Typen handeln könnte, im Gegensatz zu Any
.
Optional
- wenn es keine sein könnte . Abkürzung für Union[T, None]
.
TypeVar
- mit Generika verwendet.
Callable
- wird hauptsächlich für Funktionen verwendet, kann aber auch für andere aufrufbare Elemente verwendet werden.
Dies sind die häufigsten Typhinweise. Eine vollständige Auflistung finden Sie in der Dokumentation zum Schreibmodul .
Hier ist das alte Beispiel mit den im Schreibmodul eingeführten Anmerkungsmethoden:
from typing import List
def pick(l: List[int], index: int) -> int:
return l[index]
Eine leistungsstarke Funktion ist die Callable
, mit der Sie Annotationsmethoden eingeben können, die eine Funktion als Argument verwenden. Zum Beispiel:
from typing import Callable, Any, Iterable
def imap(f: Callable[[Any], Any], l: Iterable[Any]) -> List[Any]:
"""An immediate version of map, don't pass it any infinite iterables!"""
return list(map(f, l))
Das obige Beispiel könnte mit der Verwendung von TypeVar
anstelle von präziser werden Any
, aber dies wurde dem Leser als Übung überlassen, da ich glaube, dass ich meine Antwort bereits mit zu vielen Informationen über die wunderbaren neuen Funktionen gefüllt habe, die durch Typhinweise ermöglicht werden.
Wenn zuvor Python-Code mit beispielsweise Sphinx dokumentiert wurde, konnten einige der oben genannten Funktionen durch Schreiben von Dokumentstrings erhalten werden, die wie folgt formatiert waren:
def pick(l, index):
"""
:param l: list of integers
:type l: list
:param index: index at which to pick an integer from *l*
:type index: int
:returns: integer at *index* in *l*
:rtype: int
"""
return l[index]
Wie Sie sehen können, sind einige zusätzliche Zeilen erforderlich (die genaue Anzahl hängt davon ab, wie explizit Sie sein möchten und wie Sie Ihre Dokumentzeichenfolge formatieren). Aber jetzt sollte Ihnen klar sein, wie PEP 3107 eine Alternative bietet, die in vielerlei Hinsicht überlegen ist. Dies gilt insbesondere in Kombination mit PEP 484, das, wie wir gesehen haben, ein Standardmodul bereitstellt, das eine Syntax für diese Typhinweise / Anmerkungen definiert, die so verwendet werden kann, dass sie eindeutig und präzise und dennoch flexibel ist kraftvolle Kombination.
Meiner persönlichen Meinung nach ist dies eine der größten Funktionen in Python, die es je gab. Ich kann es kaum erwarten, dass die Leute anfangen, die Kraft davon zu nutzen. Entschuldigung für die lange Antwort, aber das passiert, wenn ich aufgeregt bin.
Ein Beispiel für Python-Code, der häufig Typhinweise verwendet, finden Sie hier .