Was ist neu in Python 3.10

[1]:
import sys


assert sys.version_info[:2] >= (3, 10)

Bessere Fehlermeldungen

Syntaxfehler

  • Beim Parsen von Code, der nicht geschlossene Klammern enthält, schließt der Interpreter jetzt die Position der nicht geschlossenen Klammer oder Klammern ein, anstatt SyntaxError: unexpected EOF anzuzeigen.

  • Vom Interpreter ausgelöste SyntaxError-Ausnahmen heben nun den gesamten Fehlerbereich des Ausdrucks hervor, in dem der Syntaxfehler besteht, anstatt nur die Stelle, an der das Problem erkannt wird.

  • Es wurden spezialisierte Meldungen für SyntaxError-Ausnahmen hinzugefügt, z.B. für

    • fehlende : vor Blöcken

    • nicht eingeklammerte Tupel in Comprehensions

    • fehlende Kommas in Auflistungsliteralen und zwischen Ausdrücken

    • fehlende : und Werte in Dictionary-Literalen

    • Verwendung von = anstelle von == in Vergleichen

    • Verwendung von * in f-strings

Einrückungsfehler

  • Viele IndentationError haben jetzt mehr Kontext.

Attribut-Fehler

  • AttributeError bieten nun Vorschläge für ähnliche Attributnamen in dem Objekt, von dem die Ausnahme ausgelöst wurde.

Name-Fehler

  • NameError bietet Vorschläge für ähnliche Variablennamen in der Funktion, von der aus die Ausnahme ausgelöst wurde.

Strukturelles Pattern-Matching

Viele funktionale Sprachen haben einen match-Ausdruck, z.B. Scala, Rust, F#.

Eine match-Anweisung nimmt einen Ausdruck und vergleicht ihn mit aufeinanderfolgenden Mustern, die als ein oder mehrere Fälle angegeben sind. Dies ist oberflächlich gesehen ähnlich wie eine switch-Anweisung in C, Java oder JavaScript, aber viel mächtiger.

match

Die einfachste Form vergleicht einen Wert mit einem oder mehreren Literalen:

[2]:
def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case 401:
            return "Unauthorized"
        case 403:
            return "Forbidden"
        case 404:
            return "Not found"
        case 418:
            return "I’m a teapot"
        case _:
            return "Something else"

Bemerkung:

Nur in diesem Fall fungiert _ als Platzhalter, der nie versagt, und nicht als Variablenname.

Die Fälle prüfen nicht nur auf Gleichheit, sondern binden Variablen neu, die dem angegebenen Muster entsprechen. Zum Beispiel:

[3]:
NOT_FOUND = 404
retcode = 200

match retcode:
    case NOT_FOUND:
        print("not found")

print(f"Current value of {NOT_FOUND=}")
not found
Current value of NOT_FOUND=200

»Wenn diese schlecht durchdachte Funktion wirklich zu Python hinzugefügt wird, verlieren wir ein Prinzip, das ich meinen Studenten immer beigebracht habe: ›Wenn du eine undokumentierte Konstante siehst, kannst du sie immer benennen, ohne die Bedeutung des Codes zu verändern.‹ Das algebraische Substitutionsprinzip? Es gilt dann nicht mehr.« – Brandon Rhodes)

«… die Semantik kann ganz anders sein als bei switch. Die Cases prüfen nicht einfach die Gleichheit, sondern binden Variablen neu, die mit dem angegebenen Muster übereinstimmen.» – Jake VanderPlas

Symbolische Konstanten

Muster können benannte Konstanten verwenden. Diese müssen Dotted Names sein, damit sie nicht als Capture-Variable interpretiert werden können:

[4]:
from enum import Enum


class Color(Enum):
    RED = 0
    GREEN = 1
    BLUE = 2


color = Color(2)

match color:
    case color.RED:
        print("I see red!")
    case color.GREEN:
        print("Grass is green")
    case color.BLUE:
        print("I’m feeling the blues :(")
I’m feeling the blues :(

»… „case CONSTANT“ passt eigentlich immer und wird einer Variablen namens CONSTANT zugewiesen« – Armin Ronacher