Python 3.10 punktet mit Structural-Pattern-Matching und besseren Fehlermeldungen
Genau ein Jahr nach der Veröffentlichung von Version 3.9 hat Python gemäß des 2020 eingeführten, schnelleren Release-Zyklus erneut ein Update erhalten. Nach über einem Jahr Entwicklungszeit und zahlreichen Beta-Releases ist V 3.10 jetzt als Stable Version verfügbar.
Strukturelles Pattern-Matching
Der Release führt nicht allzu viele Neuerungen ein, bringt mit Structural-Pattern-Matching aber eine mit sich, die unter Pythonistas als vielleicht wichtigste – wenn auch kontroverse – Ergänzung der Sprachsyntax seit async
gehandelt wird. Die Neuerung ist das Ergebnis des Versuchs, die aus anderen Programmiersprachen bekannte switch...case
-Syntax in Python einzuführen, bietet dabei aber zusätzlich eine Reihe von Möglichkeiten, die über das Vorbild hinausgehen.
Hierfür wurde Pythons Syntax um die match...case
-Struktur erweitert. Wie die Switch/Case-Struktur anderer Sprachen ermöglicht Structural-Pattern-Matching es, eine Variable mit einem Satz möglicher Werte abzugleichen. match...case
fungiert in seiner einfachsten Form quasi als Ersatz für eine if-else
-Struktur:
http_code = "418"
if http_code == "200":
print("OK")
elif http_code == "404":
print("Not Found")
elif http_code == "418":
print("Dogs are cool")
else:
print("Code not found")
# Dogs are cool
die unter Verwendung der Neuerung auch so geschrieben werden könnte:
http_code = "418"
match http_code:
case "200":
print("Ok")
case "404":
print("Not Found")
case "418":
print("Dogs are cool")
case _:
print("Code not found")
# Dogs are cool
Die Möglichkeit einer cleaneren Notation ist es allerdings nicht, was das Feature so interessant macht. Structural-Pattern-Matching erlaubt es, die Struktur von Vergleichsobjekten mit einem oder mehreren Mustern abzugleichen – beispielsweise Sequenzen (Tupel oder Listen), Dictionaries, primitiven Datentypen oder Klasseninstanzen.
Für zwei Dictionaries mit unterschiedlichen Strukturen:
In [1]:
dict_a = {
'id': 1,
'meta': {
'source': 'x',
'location': 'south'
}
}
und
In [2]:
dict_b = {
'id': 2,
'source': 'y',
'location': 'south'
}
lässt sich jeweils ein Pattern identifizieren:
#a
{
'id': int,
'meta': {'source': str,
'location': str}
}
und
#b
{
'id': int,
'source': str,
'location': str
}
Beide lassen sich dann in ein match...case
-Statement verpacken:
for d in [dict_a, dict_b, 'test']:
match d:
case {'id': ident,
'meta': {'source': source,
'location': loc}}:
print(ident, source, loc)
case {'id': ident,
'source': source,
'location': loc}:
print(ident, source, loc)
case _:
print('no match')
Gerade zur Datenverarbeitung könnte sich Structural-Pattern-Matching als echter Game-Changer erweisen. Wer tiefer einsteigen will, findet beispielsweise in diesem Video weitere Erläuterungen.
Präzisere Fehlermeldungen
Die Fehlermeldungen in Python waren lange Zeit den Launen des Parsers ausgeliefert. Mit Python 3.9 wurde ein völlig neuer Parser eingeführt – er gilt als schneller, robuster und ist für das Python-Team wohl auch leichter zu warten. Mit Version 3.10 ist er jetzt endlich offiziell verfügbar. Er bietet bessere, genauere Fehlermeldungen – so wird beispielsweise ein Syntax Error ab V 3.10 auch als solcher deklariert.
Variablen zur Spezifikation von Parametern
Mit dem Typisierungsmodul von Python, das dazu dient, Code mit Typinformationen zu versehen, können die Typen einer aufrufbaren Struktur, wie beispielsweise einer Funktion, beschrieben werden. Diese Typinformationen können nicht über sogenannte Callables hinweg weitergegeben werden. Das macht es schwierig, zum Beispiel Funktionsdekoratoren zu annotieren.
Zwei mit V 3.10 eingeführte Ergänzungen, typing.ParamSpec
und typing.Concatenate
, ermöglichen es, Callables mit abstrakteren Informationen über die Typendefinition zu annotieren. Mit ParamSpec
kann angegeben werden, wo Positions- und Keywordparameter erfasst werden sollen. Via Concatenate
kann festgelegt werden, wie Parameter hinzugefügt oder entfernt werden – ein gängiger Vorgang bei sogenannten Dekoratoren.
Das war noch längst nicht alles
Weitere Neuerungen in Python 3.10 beinhalten ein neues strict
-Keyword für die zip()
-Methode, Unterstützung für eine mehrzeilige, geklammerte Syntax für with
-Statements, eine neue, kürzere Schreibweise für sogenannte Union Types sowie die Möglichkeit, Variablen als Typen-Aliase zu definieren. Alle Änderungen und Neuerungen im Detail sind in der Doku nachzulesen.