Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Match Case в Python
Match-case — это оператор структурного сопоставления (pattern matching), введённый в Python 3.10. Это современная альтернатива множественным if-elif-else блокам, позволяющая более элегантно сравнивать значение с несколькими вариантами и выполнять разный код в зависимости от совпадения структуры данных.
Базовый синтаксис
match <subject>:
case <pattern1>:
# код если subject соответствует pattern1
case <pattern2>:
# код если subject соответствует pattern2
case _:
# default case (если ничего не совпадает)
Простой пример с точными значениями:
def describe_status(code: int) -> str:
match code:
case 200:
return "OK"
case 404:
return "Not Found"
case 500:
return "Server Error"
case _:
return "Unknown Status"
print(describe_status(200)) # "OK"
print(describe_status(404)) # "Not Found"
print(describe_status(999)) # "Unknown Status"
Сравнение с if-elif-else
Старый способ (if-elif-else):
status_code = 404
if status_code == 200:
message = "OK"
elif status_code == 404:
message = "Not Found"
elif status_code == 500:
message = "Server Error"
else:
message = "Unknown Status"
Новый способ (match-case):
status_code = 404
match status_code:
case 200:
message = "OK"
case 404:
message = "Not Found"
case 500:
message = "Server Error"
case _:
message = "Unknown Status"
Match-case более читаемо и выглядит как switch в других языках.
Паттерны сопоставления
1. Паттерны значений (Value patterns):
def check_day(day: str) -> str:
match day:
case "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday":
return "Weekday"
case "Saturday" | "Sunday":
return "Weekend"
case _:
return "Invalid day"
print(check_day("Monday")) # "Weekday"
print(check_day("Saturday")) # "Weekend"
2. Паттерны последовательностей (Sequence patterns):
Позволяют сопоставлять с элементами списков, кортежей:
def process_coords(point):
match point:
case (0, 0):
return "Origin"
case (0, y):
return f"On Y-axis at {y}"
case (x, 0):
return f"On X-axis at {x}"
case (x, y):
return f"Point at ({x}, {y})"
case _:
return "Invalid point"
print(process_coords((0, 0))) # "Origin"
print(process_coords((0, 5))) # "On Y-axis at 5"
print(process_coords((3, 4))) # "Point at (3, 4)"
3. Паттерны класса (Class patterns):
Сопоставление с объектами класса:
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
@dataclass
class Circle:
center: Point
radius: int
def describe_shape(shape):
match shape:
case Point(x=0, y=0):
return "Point at origin"
case Point(x=x, y=y):
return f"Point at ({x}, {y})"
case Circle(center=Point(x=0, y=0), radius=r):
return f"Circle at origin with radius {r}"
case Circle(center=Point(x=cx, y=cy), radius=r):
return f"Circle at ({cx}, {cy}) with radius {r}"
case _:
return "Unknown shape"
print(describe_shape(Point(0, 0))) # "Point at origin"
print(describe_shape(Point(3, 4))) # "Point at (3, 4)"
print(describe_shape(Circle(Point(0, 0), 5))) # "Circle at origin with radius 5"
4. Паттерны словарей (Mapping patterns):
def process_user(user_data):
match user_data:
case {"name": name, "age": age} if age >= 18:
return f"{name} is an adult"
case {"name": name, "age": age}:
return f"{name} is a minor (age {age})"
case {"name": name}:
return f"User {name} with unknown age"
case _:
return "Invalid user data"
print(process_user({"name": "Alice", "age": 25})) # "Alice is an adult"
print(process_user({"name": "Bob", "age": 15})) # "Bob is a minor (age 15)"
print(process_user({"name": "Charlie"})) # "User Charlie with unknown age"
5. Guards (условия в паттернах):
Можно добавлять условия с if:
def check_number(n):
match n:
case int(x) if x < 0:
return "Negative"
case int(x) if x == 0:
return "Zero"
case int(x) if x > 0:
return "Positive"
case _:
return "Not an integer"
print(check_number(-5)) # "Negative"
print(check_number(0)) # "Zero"
print(check_number(10)) # "Positive"
Пример: обработка API ответа
def handle_api_response(response):
match response:
case {"status": "success", "data": data}:
return f"Success: {data}"
case {"status": "error", "message": msg, "code": code}:
return f"Error {code}: {msg}"
case {"status": "error", "message": msg}:
return f"Error: {msg}"
case {"status": status}:
return f"Unknown status: {status}"
case _:
return "Invalid response format"
# Использование
response1 = {"status": "success", "data": {"user": "John"}}
print(handle_api_response(response1)) # "Success: {'user': 'John'}"
response2 = {"status": "error", "message": "Not found", "code": 404}
print(handle_api_response(response2)) # "Error 404: Not found"
Преимущества match-case
- Читаемость — более понятный код, чем длинные цепочки
elif - Мощность — может сопоставлять сложные структуры данных
- Безопасность типов — легче добавить type checking
- Элегантность — похоже на switch в других языках
- Композиция — можно комбинировать разные паттерны
Ограничения
- Python 3.10+ — недоступно в старых версиях Python
- Производительность — немного медленнее, чем простые
ifоператоры (из-за парсинга паттернов) - Сложность — может быть переусложненным для простых случаев
Когда использовать
- Множественные условия на одной переменной
- Сопоставление структур данных
- Обработка результатов (enum, status codes)
- Обработка вложенных данных (JSON, API responses)
Match-case — это мощный инструмент, который делает Python код более выразительным и maintainable.