Geschichte des Themas
Funktionsannotation wurden in Python 3.0 eingeführt, und der Mechanismus der Typensignaturen (type hints) ist in PEP 484 beschrieben und mit Version 3.5 hinzugefügt worden. Das Tool wurde für die statische Codeanalyse, die Autovervollständigung und die Lesbarkeit entwickelt – die Standardbibliothek typing ermöglicht es, die erwarteten Typen von Variablen, Argumenten und Rückgabewerten von Funktionen explizit anzugeben.
Problem
Python ist eine dynamische Sprache, bei der sich die Typen von Variablen zur Laufzeit ändern können, was zu Fehlern nur während der Programmausführung führen kann. Annotationen beeinflussen nicht die Ausführung des Codes, aber bei falscher Verwendung haben Programmierer ein falsches Gefühl von "strenger Typisierung".
Lösung
Typannotation werden zur Dokumentation, zur automatischen Überprüfung mit mypy, pylance, pyright und ähnlichen Tools sowie zur Integration mit IDEs verwendet. Sie werden durch einen Doppelpunkt nach dem Namen des Arguments und einen Pfeil nach der Parameterliste implementiert:**
def greet(name: str, times: int = 1) -> None: for _ in range(times): print(f"Hello, {name}!") # Korrekte Annotation für eine Funktion zur Verarbeitung eines Dictionaries from typing import Dict, List def transform(data: Dict[str, List[int]]) -> float: return sum(sum(lst) for lst in data.values()) / 10
Wichtige Merkmale:
Kann Python Typen, die in Annotationen deklariert sind, "automatisch" überprüfen?
Nein! Die Typüberprüfung erfolgt nur durch externe statische Analysetools, wie z.B. mypy. Zur Laufzeit ignoriert Python vollständig den Inhalt der Annotationen.
def f(x: int): return x * 2 print(f('oops')) # Typ str, es wird keinen Fehler geben!
Wo werden die Annotationen gespeichert und wie können sie zur Laufzeit abgerufen werden, warum könnte das wichtig sein?
Sie werden in einem speziellen Attribut annotations gespeichert:
def add(x: int, y: int) -> int: return x + y print(add.__annotations__) # {'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}
Dies nutzen externe Bibliotheken zur Datenvalidierung, zur automatischen Generierung von Dokumentationen, zur Serialisierung usw.
Kann man jede Variable annotieren, nur Funktionen, was passiert im globalen Bereich?
Man kann sowohl lokale als auch globale Variablen mit einem Doppelpunkt annotieren, dies beeinflusst ebenfalls nicht die Ausführung:
index: int = 0 def func(x: 'User') -> None: ...
In einem Unternehmensprojekt begannen alle Entwickler, aktiv Annotationen zu verwenden, die tatsächlichen Typen der Funktionsargumente stimmten jedoch oft nicht mit den angegebenen überein. Python ließ diese Fehler durch und unerwartete Bugs traten erst tief in der Geschäftslogik auf. mypy war nicht konfiguriert.
Vorteile:
Nachteile:
Einsatz von Typensignaturen und obligatorischer Ausführung von mypy in CI sowie automatische Generierung von Dokumentationen basierend auf annotations:
Vorteile:
Nachteile: