Nếu bạn đang viết một chuỗi if/elif dài để phân loại giá trị, hãy dùng match statement (có từ Python 3.10). match so khớp giá trị với các mẫu (pattern) theo thứ tự, dừng ở mẫu đầu tiên khớp, và buộc bạn nghĩ rõ trường hợp mặc định qua case _. Nó gọn hơn, đọc dễ hơn và khó sót nhánh hơn if/elif khi số trường hợp tăng lên.

Vấn đề

Chuỗi if/elif phân loại mã trạng thái HTTP là cảnh rất quen thuộc. Lúc đầu chỉ có vài nhánh, nhưng càng thêm trạng thái, code càng dài, biến điều kiện bị lặp lại ở mỗi nhánh, và rất dễ quên trường hợp còn lại:

def mo_ta_trang_thai(status):
if status == 200:
return "OK"
elif status == 404:
return "Không tìm thấy"
elif status == 500:
return "Lỗi server"
else:
return "Trạng thái khác"

Vấn đề lớn hơn xuất hiện khi giá trị cần phân loại không còn là một con số mà là một cấu trúc, ví dụ một dict lệnh nhận từ API. Với if/elif, bạn phải kiểm tra từng khóa bằng tay, code lồng nhau nhanh chóng trở nên khó đọc.

Giải pháp

match statement giải quyết đúng hai điểm này: nó so khớp theo cấu trúc, và gán biến ngay trong mẫu. Cùng ví dụ trên, viết lại bằng match:

def mo_ta_trang_thai(status):
match status:
case 200:
return "OK"
case 404:
return "Không tìm thấy"
case 500:
return "Lỗi server"
case 400 | 401 | 403:
return "Lỗi từ client"
case _:
return "Trạng thái khác"

Dấu | gộp nhiều giá trị vào một nhánh, còn case _ là trường hợp mặc định, tương đương else. Sức mạnh thật sự của match nằm ở pattern cho cấu trúc dữ liệu:

def xu_ly_lenh(lenh):
match lenh:
case {"action": "create", "name": name}:
return f"Tạo {name}"
case {"action": "delete", "id": id_} if id_ > 0:
return f"Xóa {id_}"
case _:
return "Lệnh không hợp lệ"

Một mẫu dict vừa kiểm tra khóa action, vừa trích luôn giá trị name ra biến. Phần if id_ > 0 sau mẫu gọi là guard — điều kiện phụ để nhánh chỉ khớp khi biến thỏa mãn thêm ràng buộc. Ba lưu ý quan trọng: match không có fallthrough như switch của C, nhánh đầu tiên khớp sẽ thắng nên mẫu chung phải đặt sau mẫu cụ thể, và luôn viết case _ để trường hợp lạ không lặng lẽ rơi qua mà không làm gì.

Áp dụng vào dự án của bạn

match tỏ ra hiệu quả nhất ở ba chỗ: phân loại mã trạng thái hoặc loại sự kiện, dispatch lệnh và parse JSON response từ API bên ngoài. Ngược lại, nếu điều kiện của bạn là khoảng giá trị phức tạp (ví dụ 10 <= x < 20 kèm nhiều phép so sánh), if/elif vẫn rõ ràng hơn — hoặc dùng guard trong case, nhưng đừng cố nhét mọi logic vào pattern. Quy tắc đơn giản: khi số nhánh vượt quá ba và giá trị cần phân loại có cấu trúc, hãy cân nhắc match.

Bài viết liên quan

Câu hỏi thường gặp

match có chạy nhanh hơn if/elif không?

Không đáng kể. Lợi ích chính của match là code đọc dễ hơn và khó sót nhánh hơn, không phải tốc độ. Đừng đổi sang match chỉ vì kỳ vọng hiệu năng.

match có thay thế hoàn toàn if/elif không?

Không. Điều kiện dạng khoảng giá trị, phép so sánh phức tạp hoặc logic không khớp mẫu vẫn thuộc về if/elif. match mạnh nhất khi bạn phân loại theo giá trị hoặc cấu trúc dữ liệu.

Quên viết case _ thì sao?

Không báo lỗi, nhưng giá trị không khớp nhánh nào sẽ lặng lẽ không làm gì — đúng kiểu bug khó phát hiện. Luôn thêm case _ để xử lý hoặc ít nhất ghi log trường hợp lạ.

match dùng được từ Python phiên bản nào?

Từ Python 3.10. Nếu dự án của bạn còn chạy Python 3.9 trở xuống, hãy giữ if/elif hoặc nâng cấp phiên bản trước khi dùng match.

💬 Bạn đã thử cách này trong dự án của mình chưa? Nếu gặp lỗi hoặc có cách làm gọn hơn, để lại bình luận bên dưới — mình đọc hết và sẽ bổ sung những ý hay vào bài.

Nguồn tham khảo