Annotationen, die beschreiben, nicht erzwingen
Ein Type Hint ist ein Vermerk, den du an einen Namen heftest — meist einen Funktionsparameter — und sagst: „das sollte ein int sein“, „das liefert eine Liste von Strings“ und so weiter. Python prüft ihn zur Laufzeit nicht. Einen String zu übergeben, wo du ein int annotiert hast, wirft keinen Fehler. Dein Editor und externe Werkzeuge (mypy, pyright, Pyright über VS Codes Pylance) lesen die Hints und warnen dich, bevor der Code läuft.
Der einfachste Fall:
name: str annotiert den Parameter. -> str annotiert den Rückgabewert. Beide Aufrufe laufen. Der zweite ist falsch — ein statischer Typechecker würde ihn markieren —, aber Python selbst verarbeitet ihn klaglos, weil 42 zufällig f"{...}"-Interpolation unterstützt.
Das ist das entscheidende mentale Modell: Hints sind maschinenlesbare Dokumentation. Sie ändern nichts an der Laufzeit.
Warum der Aufwand?
Drei konkrete Gewinne, nach Auszahlungsgeschwindigkeit:
- Dein Editor wird schlauer. Autovervollständigung zeigt die richtigen Methoden, Umbenennungen greifen korrekt, und ein Hover zeigt den Typ einer Variable.
- Funktionssignaturen werden selbsterklärend.
def fetch(url: str, timeout: float = 5.0) -> dict:sagt einem Leser genau, was er übergeben soll und was er zurückbekommt — ohne den Rumpf zu lesen. - Typechecker fangen Fehler vor der Ausführung ab.
mypy .auf einem Projekt zeigt die Bugs, die Unit-Tests oft verpassen —Nonezurückgegeben, wo du einen Wert erwartest, ein Dict genutzt, wo eine Liste gehört.
Für ein Einzeldatei-Skript, das nur von dir und nur heute gebraucht wird, lass die Hints weg. Für alles, worauf du zurückkommst oder was du teilst, zahlen sich die fünfzehn Sekunden zum Schreiben innerhalb einer Stunde aus.
Grundlegende eingebaute Typen
Du brauchst für keines davon einen Import:
Variablenannotationen (name: str = "Rosa") sind selten nötig — Python folgert den Typ aus der rechten Seite. Heb sie dir für Parameter, Rückgabetypen und den gelegentlichen Fall auf, in dem der geschlossene Typ unklar ist.
Funktionen, die nichts zurückgeben, nutzen -> None:
Listen, Dicts, Tupel und Sets
Container brauchen eine zweite Information — was sie enthalten. Modernes Python lässt dich die eingebauten Typen direkt indizieren:
Zum Mitlesen:
list[float]— eine Liste von Floats.dict[str, int]— ein Dict mit String-Schlüsseln und Int-Werten.tuple[float, float]— ein Tupel aus genau zwei Floats.set[str]— ein Set aus Strings.
Die Indizierungssyntax list[...], dict[...] funktioniert ab Python 3.9. In älterem Code siehst du List, Dict, Tuple aus typing importiert — gleiche Bedeutung, ältere Schreibweise.
Optionale Werte
„Könnte None sein“ ist häufig. Es hat zwei äquivalente Schreibweisen — beide okay, die neuere liest sich besser:
str | None heißt „ein String oder None“. Die |-Syntax funktioniert ab Python 3.10. In älterem Code siehst du Optional[str] aus dem Modul typing, was dasselbe bedeutet.
Eine Aufruferin, die -> str | None sieht, weiß, vor der Nutzung auf None zu prüfen — und genau darum geht es bei der Annotation.
Union-Typen: dies oder das
Kann ein Wert einer von mehreren Typen sein, nimm |:
Du kannst mehr als zwei Typen vereinigen. int | str | float heißt „irgendeiner dieser drei“.
Variablen innerhalb von Funktionen annotieren
Meistens kann Python den Typ einer lokalen Variablen aus ihrer Initialisierung erkennen. Eine Annotation brauchst du nur, wenn:
- Der Container leer startet und der Typechecker den Inhalt nicht erraten kann.
- Der Wert mehrere Typen haben könnte und du dich auf einen festlegen willst.
- Du die Absicht für eine menschliche Leserin dokumentieren willst.
typing.Any ist die Notluke — „ich will das nicht präzise annotieren“. Nutz sie sparsam. Ein Missbrauch von Any macht den Rest deiner Type Hints wertlos.
Klassen annotieren
Klassenattribute und Methodensignaturen werden wie jede andere Funktion annotiert:
Dataclasses verlangen Typannotationen — der Dekorator @dataclass liest sie, um __init__ und __repr__ zu erzeugen. Das ist die eine Stelle, an der Annotationen das Laufzeitverhalten beeinflussen.
Tupel und der „beliebige Länge“-Fall
tuple[...] hat zwei Formen, die Neulinge verwirren:
tuple[float, float]— genau zwei Floats.tuple[int, ...]— beliebig viele Ints. Das...(ein echtes Syntaxelement im Typsystem) heißt „und so weiter“.
Callables und Type-Aliase
Wenn eine Funktion eine andere Funktion nimmt oder zurückgibt, nimm Callable:
Callable[[int], int] heißt „eine Funktion, die ein int nimmt und ein int zurückgibt“.
Wird eine Annotation wiederholend, gib ihr einen Namen:
Ein Alias ist einfach eine normale Python-Zuweisung. Überall, wo du die lange Form nehmen würdest, geht der kurze Name.
Einen Typechecker ausführen
Pythons eigener Interpreter ignoriert Type Hints. Um sie tatsächlich zu prüfen, installier einen Typechecker. mypy ist das Original; pyright (das VS Codes Pylance nutzt) ist schneller.
pip install mypy
mypy your_project/
Der erste Lauf deckt Fehler an Stellen auf, die du nicht erwartet hast. Arbeite dich inkrementell durch — # type: ignore schweigt eine einzelne Zeile, wenn du weiter willst.
Moderne IDEs laufen kontinuierlich mit einem Typechecker, während du bearbeitest, das meiste Feedback kommt also, bevor du speicherst.
Wann Type Hints nicht passen
- Schnelle Erkundungsskripte. Annotationen bringen Reibung in Code, der eine Stunde lebt.
- Stark dynamischer Code. Metaprogrammierung, Plugin-Systeme und ähnliche Muster überfordern oft das Typsystem. Annotiere die äußere API und lass das Innere locker.
- Drittanbieter-Bibliotheken ohne Typen. Hat eine importierte Bibliothek keine Typinfo, sickert
Anyin deinen Code. Okay — es ist nicht dein Code zum Annotieren.
Für alles dazwischen sind Type Hints eine kleine Gewohnheit mit großem Ertrag. Die Kosten sind ein paar zusätzliche Tastendrücke pro Signatur. Der Gewinn sind weniger Bugs, leichtere Refactorings und Code, der sich selbst dokumentiert.
Als Nächstes: Module und Imports
Du hast jetzt das gesamte Funktionswerkzeug — Argumente, Dekoratoren, Type Hints. Als Nächstes sehen wir, wie Python Code über Dateien hinweg organisiert: Module, Pakete und das Import-System.
Häufig gestellte Fragen
Was sind Type Hints in Python?
Type Hints sind Annotationen, die die erwarteten Typen von Variablen, Funktionsparametern und Rückgabewerten beschreiben. Python selbst erzwingt sie zur Laufzeit nicht — sie sind für Werkzeuge (IDEs, Linter, Typechecker wie mypy oder pyright) und für Menschen, die den Code lesen.
Machen Type Hints Python schneller?
Nein. Der Python-Interpreter ignoriert Type Hints zur Laufzeit. Der Tempogewinn liegt in deiner Entwicklungsschleife — weniger Tippfehler, die der Editor auffängt, klarere Signaturen, sicherere Refactorings.
Wann soll ich Type Hints hinzufügen?
Füge sie an öffentlichen Funktionssignaturen hinzu — Parameter und Rückgabetypen. Innerhalb von Funktionen sparsam, nur wo der Typ einer Variablen nicht offensichtlich ist. Für Einmalskripte sind sie optional. Für geteilten Code und Bibliotheken zahlen sie sich schnell aus.