{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Was ist neu in Python 3.10\n",
"\n",
"
\n",
"\n",
"**Siehe auch:**\n",
"\n",
"* [What’s New In Python 3.10](https://docs.python.org/3.10/whatsnew/3.10.html)\n",
"
"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"import sys\n",
"\n",
"\n",
"assert sys.version_info[:2] >= (3, 10)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Bessere Fehlermeldungen"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Syntaxfehler\n",
"\n",
"* 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.\n",
"* 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.\n",
"* Es wurden spezialisierte Meldungen für `SyntaxError`-Ausnahmen hinzugefügt, z.B. für\n",
"\n",
" * fehlende `:` vor Blöcken\n",
" * nicht eingeklammerte Tupel in Comprehensions\n",
" * fehlende Kommas in Auflistungsliteralen und zwischen Ausdrücken\n",
" * fehlende `:` und Werte in Dictionary-Literalen\n",
" * Verwendung von `=` anstelle von `==` in Vergleichen\n",
" * Verwendung von `*` in f-strings"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Einrückungsfehler\n",
"\n",
"* Viele `IndentationError` haben jetzt mehr Kontext."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Attribut-Fehler\n",
"\n",
"* `AttributeError` bieten nun Vorschläge für ähnliche Attributnamen in dem Objekt, von dem die Ausnahme ausgelöst wurde."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Name-Fehler\n",
"\n",
"* `NameError` bietet Vorschläge für ähnliche Variablennamen in der Funktion, von der aus die Ausnahme ausgelöst wurde."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Strukturelles Pattern-Matching\n",
"\n",
"Viele funktionale Sprachen haben einen `match`-Ausdruck, z.B. [Scala](https://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html), [Rust](https://doc.rust-lang.org/reference/expressions/match-expr.html), [F#](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching).\n",
"\n",
"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."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### `match`\n",
"\n",
"Die einfachste Form vergleicht einen Wert mit einem oder mehreren Literalen:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"def http_error(status):\n",
" match status:\n",
" case 400:\n",
" return \"Bad request\"\n",
" case 401:\n",
" return \"Unauthorized\"\n",
" case 403:\n",
" return \"Forbidden\"\n",
" case 404:\n",
" return \"Not found\"\n",
" case 418:\n",
" return \"I’m a teapot\"\n",
" case _:\n",
" return \"Something else\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"**Bemerkung:**\n",
"\n",
"Nur in diesem Fall fungiert `_` als Platzhalter, der nie versagt, und **nicht** als Variablenname.\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Die Fälle prüfen nicht nur auf Gleichheit, sondern binden Variablen neu, die dem angegebenen Muster entsprechen. Zum Beispiel:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"not found\n",
"Current value of NOT_FOUND=200\n"
]
}
],
"source": [
"NOT_FOUND = 404\n",
"retcode = 200\n",
"\n",
"match retcode:\n",
" case NOT_FOUND:\n",
" print(\"not found\")\n",
"\n",
"print(f\"Current value of {NOT_FOUND=}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> »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](https://x.com/brandon_rhodes/status/1360226108399099909)\n",
"\n",
"> «… 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](https://x.com/jakevdp/status/1359870794877132810)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Symbolische Konstanten\n",
"\n",
"Muster können benannte Konstanten verwenden. Diese müssen Dotted Names sein, damit sie nicht als Capture-Variable interpretiert werden können:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"I’m feeling the blues :(\n"
]
}
],
"source": [
"from enum import Enum\n",
"\n",
"\n",
"class Color(Enum):\n",
" RED = 0\n",
" GREEN = 1\n",
" BLUE = 2\n",
"\n",
"\n",
"color = Color(2)\n",
"\n",
"match color:\n",
" case color.RED:\n",
" print(\"I see red!\")\n",
" case color.GREEN:\n",
" print(\"Grass is green\")\n",
" case color.BLUE:\n",
" print(\"I’m feeling the blues :(\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> »… \"case CONSTANT\" passt eigentlich immer und wird einer Variablen namens CONSTANT zugewiesen« – [Armin Ronacher](https://x.com/mitsuhiko/status/1359263136994516999)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"**Siehe auch:**\n",
"\n",
"* [Structural pattern matching for Python](https://lwn.net/Articles/827179/)\n",
"* [PEP 622 – Structural Pattern Matching](https://peps.python.org/pep-0622) wurde ersetzt durch\n",
"\n",
" * [PEP 634: Specification](https://peps.python.org/pep-0634)\n",
" * [PEP 635: Motivation and Rationale](https://peps.python.org/pep-0635)\n",
" * [PEP 636: Tutorial](https://peps.python.org/pep-0636)\n",
"\n",
"* [github.com/gvanrossum/patma/](https://github.com/gvanrossum/patma/)\n",
"* [playground-622.ipynb on binder](https://mybinder.org/v2/gh/gvanrossum/patma/master?urlpath=lab/tree/playground-622.ipynb)\n",
"* [Tobias Kohn: On the Syntax of Pattern Matching in Python](https://tobiaskohn.ch/index.php/2018/09/18/pattern-matching-syntax-in-python/)\n",
"