Menu

Python-Type-Hints: Annotationen für Funktionen, Listen, Dicts und mehr

Was Python-Type-Hints sind, wann sie helfen und die Syntax, um Variablen, Funktionssignaturen, Container und optionale Werte zu annotieren.

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:

main.py
Output
Click Run to see the output here.

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:

  1. Dein Editor wird schlauer. Autovervollständigung zeigt die richtigen Methoden, Umbenennungen greifen korrekt, und ein Hover zeigt den Typ einer Variable.
  2. 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.
  3. Typechecker fangen Fehler vor der Ausführung ab. mypy . auf einem Projekt zeigt die Bugs, die Unit-Tests oft verpassen — None zurü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:

main.py
Output
Click Run to see the output here.

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:

main.py
Output
Click Run to see the output here.

Listen, Dicts, Tupel und Sets

Container brauchen eine zweite Information — was sie enthalten. Modernes Python lässt dich die eingebauten Typen direkt indizieren:

main.py
Output
Click Run to see the output here.

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:

main.py
Output
Click Run to see the output here.

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 |:

main.py
Output
Click Run to see the output here.

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:

main.py
Output
Click Run to see the output here.
  • 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:

main.py
Output
Click Run to see the output here.

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:

main.py
Output
Click Run to see the output here.
  • 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:

main.py
Output
Click Run to see the output here.

Callable[[int], int] heißt „eine Funktion, die ein int nimmt und ein int zurückgibt“.

Wird eine Annotation wiederholend, gib ihr einen Namen:

main.py
Output
Click Run to see the output here.

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 Any in 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.

Lerne mit Coddy zu programmieren

LOS GEHT'S