Guido van Rossum proposed to include operators for pattern matching in Python

Guido van Rossum presented draft for community review spit-up for the implementation in the Python language of the operators for pattern matching (match and case). It should be noted that proposals to add pattern matching operators were already published in 2001 and 2006 (pep-0275, pep-3103), but were rejected in favor of optimizing the "if ... elif ... else" construct for compiling matching chains.

The new implementation is much like the "match" operator provided in Scala, Rust, and F#, which compares the result of executing a specified expression against a list of patterns listed in blocks based on the "case" operator. Unlike the "switch" operator available in C, Java, and JavaScript, "match"-based expressions offer much more wide functionality. It is noted that the proposed operators will improve the readability of the code, simplify the comparison of arbitrary Python objects and debugging, and also increase the reliability of the code due to the possibility of extended static type checking.

def http_error(status):
match status:
case 400:
return "Bad request"
case 401|403|404:
return "Not allowed"
case 418:
return "I'm a teapot"
case_:
return "Something else"

For example, you can unpack objects, tuples, lists, and arbitrary sequences to bind variables based on available values. It is allowed to define nested templates, use additional "if" conditions in the template, use masks ("[x, y, *rest]"), mapping key/value bindings (for example, {"bandwidth": b, "latency": l} to extract "bandwidth" and "latency" values ​​and a dictionary), extract subpatterns (the ":=" operator), use named constants in the template. In classes, it is possible to customize the matching behavior using the "__match__()" method.

from dataclasses import dataclass

@dataclass
classPoint:
x:int
y:int

def whereis(point):
match point:
case Point(0, 0):
print("Origin")
case Point(0, y):
print(f"Y={y}")
casePoint(x, 0):
print(f"X={x}")
casePoint():
print("somewhere else")
case_:
print("Not a point")

match point:
case Point(x, y) if x == y:
print(f"Y=X at {x}")
casePoint(x, y):
print(f"Not on the diagonal")

RED, GREEN, BLUE = 0, 1, 2
match color:
case .RED:
print("I see red!")
case .GREEN:
print("Grass is green")
case .BLU
E:
print("I'm feeling the blues :(")

A set has been prepared for review patches with experimental implementation the proposed specification, but the final version is still being discussed. For example, offered instead of the expression "case _:" for the default value, use the keyword "else:" or "default:", since "_" in other contexts is used as a temporary variable. Also of concern is the internal organization based on translating new expressions into bytecode, similar to that used for "if ... elif ... else" constructs, which will not provide the desired performance when processing very large sets of comparisons.

Source: opennet.ru

Add a comment