Die Version von Python 3.10 , an der am 25. Mai 2020 begonnen wurde, soll am 4. Oktober 2021 veröffentlicht werden und eine Reihe interessanter Neuerungen enthalten. Eine der vielversprechendsten Innovationen wird der strukturierte Mustervergleich (strukturierter Mustervergleich) sein. Hierzu wird eine spezielle Mustervergleichsanweisung eingeführt match
. Die Pattern Matching-Funktionalität wird zweifellos von Interesse sein, insbesondere für FP-Programmierer, wo sie eine wichtige Rolle spielt. Der Rest der Neuheiten der neuen Version der Sprache wird hier beschrieben .
Python hatte trotz all seiner Leistungsfähigkeit und Popularität lange Zeit nicht die Form der Flusskontrolle, die in anderen Sprachen zu finden war - eine Möglichkeit, einen Wert zu nehmen und ihn elegant einer von vielen möglichen Bedingungen zuzuordnen. In den Sprachen C und C ++ erfolgt dies durch ein Konstrukt switch/case
. In Rust und F # wird dieses Konstrukt als Mustervergleich bezeichnet.
Die traditionellen Methoden in Python sind nicht elegant. Eine davon ist, eine Kette von Ausdrücken zu schreiben if/elif/else
. Eine andere Möglichkeit besteht darin, Werte zu speichern, die als Schlüssel in einem Wörterbuch übereinstimmen, und dann die Werte nach Schlüssel zu verwenden, um eine Aktion auszuführen - beispielsweise eine Funktion als Wert zu speichern und einen Schlüssel oder eine andere Variable als Eingabe zu verwenden. In vielen Fällen funktionieren diese Techniken gut, sind jedoch umständlich zu entwerfen und zu warten.
Python , switch/case
, Python 3.10 Python : . switch/case
, .
Python
Python
Python match/case
. match/case
, switch/case
. , , .
match command:
case "quit":
quit()
case "reset":
reset()
case unknown_command:
print (f" '{unknown_command}')
case
, . .
Python , . Python case
, match
. case
«», case
( ).
. case
, unknown_command
, «» unknown_command, .
. case
, , . case
, .
, , . :
from enum import Enum
class Command(Enum):
QUIT = 0
RESET = 1
match command:
case Command.QUIT:
quit()
case Command.RESET:
reset()
; . , , , Python.
, , , , . , , , .
. , .
command = input()
match command.split():
case [""]:
quit()
case ["", filename]:
load_from(filename)
case ["", filename]:
save_to(filename)
case _:
print (f" '{command}'")
case
:
case [""]:
, , ""
, .
case ["", filename]:
, ""
, . , filename
. case ["", filename]:
.
case _:
. , . , _
; _
match
, () ( command
case
; .)
, . :
case "a":
"a"
.
case ["a","b"]:
["a","b"]
.
case ["a", value1]:
, value1
.
case ["a", *values]:
, , . , , . , ( Python).
case ("a"|"b"|"c"):
(|
) , case
case
. "a"
, "b"
, "c"
.
case ("a"|"b"|"c") as letter:
, , letter
.
case ["a", value] if <>:
, . . , if
valid_values
, case
, .
case ["z", _]:
, "z"
.
Python , . , media_object
.jpg .
match media_object:
case Image(type="jpg"):
#
return media_object
case Image(type="png") | Image(type="gif"):
return render_as(media_object, "jpg")
case Video():
raise ValueError(" ")
case other_type:
raise Exception(f" {media_object} ")
case
, . case
Image
, "jpg"
. case
, "png"
"gif"
. case
, Video
, . case
, .
:
match media_object:
case Image(type=media_type):
print (f" {media_type}")
Python , , . , , , . , .
, . , , . , if/elif/else
, , - . , - .
, if/elif/else
— ! , . , .
:
switch/case
# :
#
# Python 3.10.
# switch/case
def match_errno(errno):
match errno:
case 0:
pass
case 1:
pass
case 42:
print("42!")
case _: #
print(" ")
#
def command_split(command):
match command.split():
case ["make"]:
print("make ")
case ["make", cmd]:
print(f" make: {cmd}")
case ["restart"]:
print(" ")
case ["rm", *files]:
print(f" : {files}")
case _:
print(" ")
(|)
# (|)
def match_alternatives(command):
match command.split():
case [""] | [" ", ""]:
print(" ")
case ["", obj] | ["", " ", obj] | ["", obj, " "]:
print(f" : {obj}")
as
# as
def match_capture_subpattern(command):
match command.split():
case [" ", ("" | "" | "" | "") as direction]:
print(f" {direction}")
if
# if
def match_guard(command, exits):
match command.split():
case [" ", direction] if direction in exits:
print(f" {direction}")
case [" ", _]:
print(f" ")
#
from dataclasses import dataclass
@dataclass
class Click:
position: tuple[int, int]
button: str
@dataclass
class KeyPress:
key_name: str
@dataclass
class Quit:
pass
def match_by_class(event):
match event:
case Click(position=(x,y), button="left"):
print(f" {x,y}")
case Click(position=(x,y)):
print(f" {x,y}")
case KeyPress("Q"|"q") | Quit():
print(" ")
case KeyPress(key_name="up arrow"):
print(" ")
case KeyPress():
pass #
case other_event:
raise ValueError(f' : {other_event}')
#
def match_json_event(event):
match event:
case {"transport": "http"}:
print(" insecure ")
case {"verb": "GET", "page": "articles", "pageno": n}:
print(f" {n}...")
case {"verb": "POST", "page": "signup"}:
print(" ")
:
def main():
# x, y = 1, 2
command_split("make")
command_split("make clean")
command_split("restart")
command_split("rm a b c")
command_split("doesnt match")
match_errno(42)
match_alternatives("go north")
match_alternatives("pick up sword")
match_capture_subpattern("go north")
match_capture_subpattern("go east")
match_guard("go north", exits=["east", "south"])
match_guard("go north", exits=["north"])
match_by_class(Click(position=(0,0), button="left"))
match_by_class(Quit())
try:
match_by_class("BADVALUE")
except ValueError:
pass
match_json_event({"verb": "GET", "page": "articles", "pageno": 5, "info": "extra"})
pass
if name == 'main':
main()