Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.
Làm chủ Pattern Matching trong Python 3.10
Pattern Matching là một trong những tính năng mới thú vị nhất trong phiên bản Python 3.10. Trong bài viết này, bạn sẽ học mọi thứ cần biết về nó!Tính năng này dễ hiểu nhưng cung cấp rất nhiều cú pháp và cách sử dụng khác nhau. Chúng ta sẽ bắt đầu từ cú pháp cơ bản và sau đó khám phá các chi tiết phức tạp hơn.
Tham khảo: Nhiều ví dụ được lấy từ tài liệu chính thức: What's New In Python 3.10.
Cú pháp cơ bản trong Python
Cú pháp rất dễ hiểu. Sử dụng từ khóa match
và case
để so khớp một biến với các giá trị khác nhau. Với mỗi trường hợp (case
) được khớp, bạn có thể thực hiện hành động tương ứng.
Ví dụ:
Bài viết này được đăng tại [free tuts .net]
def http_error(status): match status: case 400: return "Bad request" case 401 | 403: return "Not allowed" case 404: return "Not found" case 418: return "I'm a teapot" case _: return "Something's wrong with the internet"
Ở ví dụ này, chúng ta so khớp giá trị status
với các trường hợp cụ thể (400, 401,...) hoặc dùng _
làm ký tự đại diện khi không có trường hợp nào phù hợp.
So khớp nhiều giá trị
Dùng toán tử |
để so khớp với nhiều giá trị trên một dòng:
def http_error(status): match status: case 400: return "Bad request" case 401 | 403 | 404: return "Not allowed"
Không có "fall through"
Khác với một số ngôn ngữ như C++, Python không tự động tiếp tục chạy các trường hợp sau. Ví dụ:
def http_error(status): match status: case 400: print("Bad request") case 401 | 403 | 404: print("Not allowed")
Ở đây, nếu status = 400
, chỉ in "Bad request" và không chạy các dòng tiếp theo.
Ký tự đại diện (Wildcard
) trong Python
Ký tự _
được dùng làm ký tự đại diện khi không có trường hợp nào phù hợp.
def http_error(status): match status: case 400: return "Bad request" case _: return "Something's wrong with the internet"
Giải nén và gán biến
Pattern Matching có thể dùng để giải nén dữ liệu và gán giá trị vào biến.
Ví dụ: So khớp một tuple và giải nén thành tọa độ x, y:
match point: case (0, 0): print("Origin") case (0, y): print(f"Y={y}") case (x, 0): print(f"X={x}") case (x, y): print(f"X={x}, Y={y}") case _: raise ValueError("Not a point")
So khớp với class
Pattern Matching hỗ trợ so khớp với các thuộc tính của class.
Ví dụ:
from dataclasses import dataclass @dataclass class Point: x: int y: int def location(point): match point: case Point(x=0, y=0): print("Origin is the point's location.") case Point(x=0, y=y): print(f"Y={y} and the point is on the y-axis.") case Point(x=x, y=0): print(f"X={x} and the point is on the x-axis.") case Point(): print("The point is located somewhere else.") case _: print("Not a point")
Tham số vị trí và tham số từ khóa
Có thể dùng cả tham số vị trí hoặc tham số từ khóa khi so khớp với class.
Point(1, var) Point(1, y=var) Point(x=1, y=var) Point(y=var, x=1)
So khớp lồng nhau
Pattern Matching cũng hỗ trợ so khớp dữ liệu lồng nhau, ví dụ danh sách chứa các đối tượng:
points = [Point(0, 0), Point(1, 1)] match points: case []: print("No points in the list.") case [Point(0, 0)]: print("The origin is the only point in the list.") case [Point(x, y)]: print(f"A single point {x}, {y} is in the list.") case [Point(0, y1), Point(0, y2)]: print(f"Two points on the Y axis at {y1}, {y2}.") case _: print("Something else is in the list.")
Pattern với Enum trong Python
Có thể dùng Pattern Matching với Enum:
from enum import Enum class Color(Enum): RED = 0 GREEN = 1 BLUE = 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 :(")
Sử dụng Guard với if
Có thể thêm điều kiện (guard
) để lọc các trường hợp cụ thể hơn:
match point: case Point(x, y) if x == y: print(f"The point is located on the diagonal Y=X at {x}.") case Point(x, y): print("Point is not on the diagonal.")