Zum Hauptinhalt springen

Von wegen untypisiert!

 

Starke Typisierung zur Laufzeit

Die Behauptung „Python ist keine typisierte Sprache“ erhöht meinen Puls mittlerweile genauso wie das vor vielen Jahren übliche „Python ist nur eine Scriptsprache“.

Man muss nur schnell eine Python-Konsole öffnen und 1+"1" eingeben. Das Ergebnis ist nicht, wie z. B. bei PHP, eine 2, sondern ein TypeError. Python ist sehr wohl stark typisiert und unterscheidet zudem auch noch zwischen mutable und immutable types. Da der Code in Python erst zur Laufzeit kompiliert wird, fällt der gerade genannte Additionsfehler an sich nicht beim Programmieren, sondern erst bei der Ausführung auf.

 

Duck-Typing

In Python soll trotz starker Typisierung zur Laufzeit in der Programmierung keine zwingende Festlegung auf einen Variablentyp erfolgen. Man folgt dem Prinzip des Duck-Typings. Wenn ein Vogel „Quack“ machen kann, dann wird es wohl eine Ente sein, egal ob Stockente oder Kragenente. Genauso ist es zunächst egal, ob eine Variable einen Integer- oder Float- oder Double-Wert beinhaltet, wenn ich addieren und multiplizieren will.

 

Hungarian Notation: Finger weg!

Den Variablentyp bereits beim Programmieren zu erkennen, führte vor über 30 Jahren zu Coding-Standards wie der „Hungarian Notation“, bei der man den Typ dem Variablennamen als Prefix beifügt. Zum Beispiel nCustomers soll dem Entwickler mitteilen, dass es sich um eine numerische Kundenzahl handelt. Dieses aus heutiger Sicht kuriose Relikt aus dem letzten Jahrtausend ist durch moderne Entwicklungsumgebungen natürlich längst überflüssig. Dennoch habe ich das ein oder andere Unternehmen gesehen, das es tatsächlich noch lebt. Bitte nicht, das gehört ins Museum.

 

Type-Hinting in PyCharm

Heute werden Entwickler durch ausgefeilte IDEs unterstützt. Ich habe für Python vor 10 Jahren mit der Eclipse-IDE angefangen, bin irgendwann auf die Wing-IDE umgestiegen und schließlich vor rund 3 Jahren bei PyCharm von Jetbrains gelandet. Seitdem ich nun das Jetbrains-Package auf dem Rechner habe, benötige ich keine anderen IDEs mehr, nicht mal für SQL. Für Python bietet PyCharm immer die volle Unterstützung der neuesten Features und ab Python 3.5 eben auch für Type-Hinting.

Das neue Type-Hinting ist von den Python-Entwicklern, allen voran Guido von Rossum, explizit nur als optionale Unterstützung gedacht. In der PEP484 steht: “It should also be emphasized that Python will remain a dynamically typed language, and the authors have no desire to ever make type hints mandatory, even by convention.”

 

Ein simples Beispiel

Der hier gezeigte Code enthält eine einfache Beispiel-Klasse mit einer Reihe von Funktionen.

 

 Code: Beispiel-Klasse mit Funktionen

 

  • Zeile 8 zeigt im Constructor das Type-Hinting von Parametern, nämlich mit Doppelpunkt nach dem Parameter, gefolgt vom Typ.
  • Zeile 12 zeigt eine Methodendeklaration mit Rückgabewert, nämlich mit dem Pfeil "->" und dem Typ zwischen Klammer und Doppelpunkt.
  • Zeile 15 zeigt eine Methodendeklaration mit mehreren möglichen Rückgabewerten. Das "Union" muss hierbei vom typing-Modul erst importiert werden (Zeile 1).
  • Zeile 6 zeigt eine Attributdefinition mit type. Diese Schreibweise kann auch überall verwendet werden, wo Variablen deklariert werden!

Was passiert, wenn ich mich nicht daran halte? 

 

pycharm-codeinterpretation

 

PyCharm interpretiert laufend in Echtzeit den Code, bereitet die Type-Hints auf und gibt dem User Hinweise auf mögliche Fehler, ohne den Code ausführen zu müssen.

  • In Zeile 12 ist der Code hervorgehoben, da PyCharm merkt, dass zwar ein int als Rückgabe gefordert ist, aber aus lower() nur ein str resultieren kann.
  • In Zeile 24 und 26 sind meine Parameterwerte hervorgehoben, da die Typen offensichtlich nicht zu denen in der Methodendefinition passen.

Die IDE geht hier sogar noch einen Schritt weiter und interpretiert den Code nach gewissen Regeln. Nachfolgender Code zeigt z. B., wie mit dem Parameter "base" im Methodenaufruf umgegangen wird. Es ist zunächst kein Typ angegeben, aber die IDE erkennt am Code der nächsten Zeile, dass damit multipliziert wird. Also wird abgeleitet, dass, im Sinne von Duck-Typing, es zunächst egal ist, was übergeben wird, solange es die buildin-Methode für Multiplikation "__mul__" beinhaltet.

 

methodenaufruf-base

 

Die Methodenansicht im letzten Screenshot erhält man übrigens am schnellsten, wenn man eine Methode oder Funktion mit dem Cursor selektiert und einfach STRG+Q drückt. Alternativ kann man auch beim Tippen, sobald man die Klammer für die Parameter geöffnet hat, STRG+P drücken und man erhält sofort einen Tooltip mit den Parametern und den dazu definierten Typen. Wie hier:

 

methodenansicht

 

Soll man nun seine Codes alle umschreiben?


Hints als Mindeststandard für Code-Dokumentation
 

Natürlich ist das nicht notwendig. Wie oben erwähnt, dient das Type-Hinting nur zur optionalen Unterstützung. Wenn der Python-Interpreter den Code ausführt, ignoriert er alle Type-Hints gnadenlos, da sie nur als Hinweise für die IDEs gedacht sind, und schiebt sie in ein Metadatenobjekt namens "__annotations__".

Ich persönlich sehe aber eine große Chance darin, einen Code präziser zu dokumentieren. Immer wenn ich Type-Hints setze, dann teile ich sofort anderen Usern und mir in der Zukunft mit, wie der Code optimal zu bedienen ist. Natürlich gab es das schon immer auch über Code-Kommentare, aber diese hatten wenig Konsequenz darin, schon beim Entwickeln auf Fehler hinzuweisen.


Unterstützung in der Arbeit als Data Scientist
 

Python in der Data Science bedeutet für mich Pandas und PySpark. Ich persönlich schreibe meinen Code immer in einem Editor in PyCharm und schicke den Code dann per Tastenkombination selektiv zum Interpreter. Hier habe ich ständig das Problem, dass die Autovervollständigung hinterherhinkt, da die verwendeten Methoden nicht immer die Rückgabewerte korrekt angegeben haben. In Pandas z. B. passiert es schnell, dass ein Dataframe nicht mehr im Editor als solches erkannt wird. Dafür kann die IDE nichts, wenn das importierte Modul die Metadaten nicht mitliefert. Sobald ich aber hier und da "df: DataFrame = ..." statt einfach nur "df = ..." schreibe, nimmt die IDE den Faden sofort wieder auf und bietet mir in der Autovervollständigung wieder alle Infos.

 

Ausblick

PyCharm deckt noch nicht alle Fälle von Type-Hinting mit User-Hinweisen ab. Das heißt, der Editor unterstützt zwar alle neuen Schreibweisen, verhält sich aber noch etwas konservativ, was Fehlerhinweise angeht. Man muss auch bedenken, dass die Vorschläge für das eindeutige Format von Type-Hints zwar schon recht alt sind, aber die Unterstützung erst mit Python 3.5 eingeführt wurde. Selten findet man in Unternehmen eine so aktuelle Python-Installation vor, so dass es erstmal ein Thema der eigenen Entwicklungsumgebung sein wird. Bei den quartalsweisen Updates von PyCharm ist aber zu erwarten, dass die Entwicklerunterstützung stetig weiter reift.

Die Funktionalität des typing-Moduls reicht noch viel weiter als das, was ich hier vorgestellt habe. Mehr Infos findet man direkt in der Python-Doku unter docs.python.org/3.6/library/typing.html .