37. Kết hợp mẫu

biên dịch đối sánh/trường hợp thành mã MATCH_*, ngữ nghĩa mẫu và đánh giá bảo vệ trong trình thông dịch.

37. Khớp mẫu

Khớp mẫu là hệ thống khớp cấu trúc của Python. Nó được thực hiện bởimatchtuyên bố vàcasekhoản.```python match value: case 0: result = "zero" case [x, y]: result = x + y case {"name": name}: result = name case _: result = None


Ở cấp độ CPython, việc so khớp mẫu được biên dịch thành mã byte thông thường cộng với các hướng dẫn so khớp chuyên biệt. Trình thông dịch đánh giá chủ đề, thử từng trường hợp theo thứ tự, liên kết các tên để khớp thành công và chuyển đến nội dung đã chọn.

## 37.1`match`Tuyên bố

A`match`câu lệnh có một biểu thức chủ ngữ và một hoặc nhiều trường hợp.```python
match subject:
    case pattern:
        body
    case pattern if guard:
        body
    case _:
        body
```Biểu thức chủ đề được đánh giá một lần.```python
match compute():
    case 1:
        ...
    case 2:
        ...

compute()chạy một lần. Kết quả sau đó được kiểm tra đối với các trường hợp từ trên xuống dưới.

Về mặt khái niệm:```text subject = compute()

try case 1 if match succeeds: execute case 1 body else: try case 2


## 37.2 Mẫu và Biểu thức

Các mẫu trông giống như các biểu thức nhưng chúng tuân theo các quy tắc khác nhau.```python
match value:
    case x:
        ...
```Điều này không so sánh`value`với một biến hiện có`x`. Nó bắt chủ đề vào một tên mới`x`.

Một mô hình chụp luôn thành công.```python
case x:
```có nghĩa:```text
bind x = subject
match succeeds
```Để so sánh với một hằng số được đặt tên, hãy sử dụng tên có dấu chấm:```python
case Color.RED:
```hoặc sử dụng một người bảo vệ:```python
case x if x == expected:
```Sự khác biệt này rất quan trọng vì việc khớp mẫu có cú pháp và quy tắc ràng buộc riêng.

## 37.3 Lệnh trường hợp

Các vụ án được xét xử theo thứ tự.```python
match value:
    case int():
        result = "integer"
    case bool():
        result = "boolean"
```Đây là một mệnh lệnh tồi vì`bool`là một lớp con của`int`.

```python
isinstance(True, int)
```là đúng.

Vì thế`True`trận đấu`int()`trước khi đạt được`bool()`.

Tốt hơn:```python
match value:
    case bool():
        result = "boolean"
    case int():
        result = "integer"
```Khớp mẫu sử dụng loại và cấu trúc thời gian chạy. Các trường hợp cụ thể hơn thường xuất hiện trước các trường hợp tổng quát hơn.

## 37.4 Mẫu ký tự đại diện

Mẫu ký tự đại diện`_`phù hợp với bất cứ điều gì và không ràng buộc gì.```python
match value:
    case 0:
        result = "zero"
    case _:
        result = "other"
```các`_`mẫu thường được sử dụng làm dự phòng cuối cùng.

Nó khác với tên chụp thông thường:```python
case name:
```Điều này ràng buộc`name`.

```python
case _:
```Điều này không ràng buộc`_`với tư cách là người địa phương mới cho kết quả trận đấu.

## 37.5 Mẫu chữ

Các mẫu chữ khớp với các giá trị như số, chuỗi, byte, boolean và`None`.

```python
match value:
    case 0:
        result = "zero"
    case "ok":
        result = "success"
    case None:
        result = "missing"
```Đối với hầu hết các nghĩa đen, việc so khớp sử dụng ngữ nghĩa bình đẳng.```text
subject == literal
```Đối với các hằng số đơn như`None`, `True`, Và`False`, việc so khớp sử dụng ngữ nghĩa đơn lẻ theo kiểu nhận dạng.

Các mẫu chữ rất hữu ích cho các thẻ, trạng thái nhỏ và đánh dấu giao thức.

## 37.6 Mẫu chụp

Một mẫu chụp liên kết một tên.```python
match value:
    case x:
        result = x
```Điều này luôn phù hợp.

Các mẫu chụp rất hữu ích bên trong các mẫu lớn hơn:```python
match point:
    case [x, y]:
        result = x + y
```Đây,`[x, y]`là một mẫu tuần tự. Những cái tên`x`Và`y`nắm bắt các yếu tố.

Sau khi khớp thành công, các tên bị ràng buộc sẽ có sẵn trong nội dung trường hợp.```python
match value:
    case [x, y]:
        print(x, y)
```Nếu khớp không thành công, các ràng buộc từ mẫu không thành công đó không được rò rỉ theo cách mà mã người dùng có thể dựa vào.

## 37.7 Mẫu giá trị

Mẫu giá trị so sánh chủ đề với giá trị được tham chiếu bằng tên có dấu chấm.```python
match color:
    case Color.RED:
        handle_red()
    case Color.BLUE:
        handle_blue()
```Tên có dấu chấm được đánh giá và so sánh với chủ đề.

Điều này khác với:```python
case RED:
```mà nắm bắt được một cái tên gọi là`RED`.

Đối với các hằng số, hãy sử dụng tên có dấu chấm, enum hoặc bộ bảo vệ.```python
class Status:
    OK = "ok"
    ERROR = "error"

match status:
    case Status.OK:
        ...
```## 37.8 HOẶC Mẫu

Mẫu OR khớp nếu có bất kỳ mẫu thay thế nào khớp.```python
match value:
    case 0 | 1 | 2:
        result = "small"
```Tất cả các lựa chọn thay thế phải liên kết cùng một bộ tên.

Có hiệu lực:```python
match value:
    case [x] | (x,):
        result = x
```Về nguyên tắc không hợp lệ:```python
case [x] | [x, y]:
```bởi vì sự thay thế đầu tiên liên kết`x`, trong khi thứ hai liên kết`x`Và`y`.

Trình biên dịch kiểm tra tính nhất quán liên kết tên cho các mẫu OR.

## 37.9 NHƯ mẫu

Mẫu AS liên kết toàn bộ giá trị khớp trong khi cũng khớp với mẫu con.```python
match value:
    case [x, y] as pair:
        print(x, y, pair)
```Nếu chủ đề phù hợp`[x, y]`, sau đó:```text
x = first element
y = second element
pair = whole subject
```Điều này hữu ích khi bạn cần cả trường bị hủy cấu trúc và giá trị ban đầu.

## 37.10 Vệ binh

Người bảo vệ là một`if`điều kiện gắn liền với một trường hợp.```python
match value:
    case [x, y] if x < y:
        result = "ascending"
```Mẫu này được khớp đầu tiên. Nếu thành công, người bảo vệ sẽ được đánh giá.

Về mặt khái niệm:```text
if subject matches [x, y]:
    if x < y:
        execute body
    else:
        try next case
```Các vệ sĩ có thể chạy mã Python tùy ý. Họ có thể đưa ra các ngoại lệ, gọi hàm, thay đổi trạng thái hoặc phụ thuộc vào tên đã ghi.

Nếu người bảo vệ đánh giá là sai, trường hợp đó được coi là không được chọn và việc so khớp sẽ tiếp tục với trường hợp tiếp theo.

## 37.11 Mẫu trình tự

Mẫu trình tự khớp với các đối tượng giống trình tự.```python
match value:
    case [x, y]:
        result = x + y
```Điều này phù hợp với chuỗi có độ dài hai.

Ví dụ có thể phù hợp:```python
[1, 2]
(1, 2)
```Chuỗi và byte không được coi là chuỗi cho mục đích này, mặc dù chúng giống chuỗi trong các ngữ cảnh khác.

So khớp trình tự cần kiểm tra:```text
is the subject a sequence pattern candidate
does it have the required length
extract elements
match nested subpatterns
bind names
```## 37.12 Mẫu trình tự được gắn dấu sao

Mẫu được gắn dấu sao sẽ ghi lại phần giữa có độ dài thay đổi.```python
match value:
    case [first, *middle, last]:
        ...
```Vì:```python
value = [1, 2, 3, 4]
```các ràng buộc là:```text
first = 1
middle = [2, 3]
last = 4
```Ảnh chụp được gắn dấu sao nhận được một danh sách.

Mẫu yêu cầu ít nhất đủ phần tử cho các vị trí không được gắn dấu sao.```python
case [first, *middle, last]:
```cần ít nhất hai phần tử.

## 37.13 Mẫu ánh xạ

Mẫu ánh xạ khớp với các đối tượng giống như ánh xạ.```python
match value:
    case {"name": name, "age": age}:
        ...
```Điều này kiểm tra xem chủ đề có các khóa cần thiết hay không.

Vì:```python
value = {"name": "Ada", "age": 37, "city": "London"}
```mẫu khớp và liên kết:```text
name = "Ada"
age = 37
```Các khóa bổ sung được cho phép trừ khi mẫu sử dụng logic chặt chẽ hơn bên ngoài mẫu, chẳng hạn như bộ bảo vệ.

Các mẫu ánh xạ cũng có thể chụp các mục còn lại:```python
match value:
    case {"name": name, **rest}:
        ...
```Sau đó`rest`nhận được một từ điển các khóa chưa khớp.

## 37.14 Mẫu lớp

Các mẫu lớp khớp với các đối tượng theo loại và thuộc tính.```python
match value:
    case Point(x, y):
        ...
```Điều này kiểm tra xem`value`là một ví dụ của`Point`, sau đó trích xuất các trường.

Ý nghĩa của các trường vị trí được kiểm soát bởi`Point.__match_args__`.

Ví dụ:```python
class Point:
    __match_args__ = ("x", "y")

    def __init__(self, x, y):
        self.x = x
        self.y = y
```Sau đó:```python
match p:
    case Point(x, y):
        ...
```về mặt khái niệm tương tự như:```text
isinstance(p, Point)
x = p.x
y = p.y
```với ngữ nghĩa khớp mẫu và hành vi lỗi.

## 37.15 Mẫu lớp từ khóa

Các mẫu lớp có thể đặt tên các thuộc tính một cách rõ ràng.```python
match value:
    case Point(x=0, y=y):
        ...
```Điều này phù hợp với một`Point`của ai`x`thuộc tính phù hợp`0`, và ràng buộc`y`thuộc tính.

Các mẫu lớp từ khóa không phụ thuộc vào`__match_args__`cho những thuộc tính đó.

Về mặt khái niệm:```text
check isinstance(value, Point)
get value.x and match against 0
get value.y and bind y
```Tra cứu thuộc tính có thể thực thi mã, vì vậy các mẫu lớp có thể có tác dụng phụ nếu liên quan đến các thuộc tính hoặc quyền truy cập thuộc tính tùy chỉnh.

## 37,16`__match_args__`

`__match_args__`ánh xạ các trường mẫu lớp vị trí vào tên thuộc tính.```python
class Point:
    __match_args__ = ("x", "y")
```Điều này cho phép:```python
case Point(a, b):
```có nghĩa là:```python
case Point(x=a, y=b):
```Đối với các lớp dữ liệu và các bộ dữ liệu được đặt tên, Python thường cung cấp các`__match_args__`tự động.

Nếu như`__match_args__`bị thiếu, trống hoặc không tương thích, các mẫu lớp vị trí có thể bị lỗi hoặc phát sinh lỗi tùy thuộc vào dạng mẫu.

## 37.17 Mẫu lồng nhau

Các mẫu có thể lồng nhau.```python
match value:
    case {"point": Point(x, y), "label": label}:
        ...
```Điều này kiểm tra:```text
subject is a mapping
subject has key "point"
subject has key "label"
subject["point"] is a Point
extract Point.x and Point.y
bind label
```Các mẫu lồng nhau được biên dịch thành một chuỗi các hoạt động kiểm tra và trích xuất.

Nếu bất kỳ phần lồng nhau nào bị lỗi thì toàn bộ trường hợp sẽ không thành công và việc so khớp sẽ tiếp tục với trường hợp tiếp theo.

## 37.18 Ràng buộc tên

Tên bị ràng buộc trong trường hợp thành công sẽ trở thành các biến cục bộ trong phạm vi xung quanh.```python
def f(value):
    match value:
        case [x, y]:
            return x + y
        case _:
            return 0
```Trình biên dịch xử lý`x`Và`y`như tên địa phương trong`f`.

Điều này có thể ảnh hưởng đến việc phân tích phạm vi. Tên được một mẫu ghi lại là một sự xuất hiện ràng buộc, tương tự như sự gán.

Ví dụ:```python
def f(value):
    match value:
        case x:
            return x
```Đây,`x`là địa phương để`f`.

## 37.19 Liên kết khớp không thành công

Không nên sử dụng mẫu bị lỗi làm nguồn liên kết ổn định.

Ví dụ:```python
match value:
    case [x, 0]:
        ...
    case _:
        ...
```Nếu trường hợp đầu tiên không thành công sau khi liên kết một phần của cấu trúc, CPython phải tránh để lộ các liên kết một phần là kết quả thành công.

Ngữ nghĩa ngôn ngữ không cho phép bạn dựa vào tên bị ràng buộc trong các trận đấu thất bại.

Mã trình biên dịch và trình thông dịch phải tuân theo quy tắc này.

## 37.20 Mã byte khớp mẫu

So khớp mẫu sẽ biên dịch thành mã byte.

Một ví dụ đơn giản:```python
def f(value):
    match value:
        case [x, y]:
            return x + y
        case _:
            return 0
```Cấu trúc mã byte khái niệm:```text
load subject

try sequence case:
    check sequence
    check length 2
    unpack into x, y
    execute body
    return

fallback:
    return 0
```CPython bao gồm các mã opcode dành riêng cho mẫu để kiểm tra thông thường, chẳng hạn như khớp trình tự, khớp ánh xạ, trích xuất khóa và khớp lớp. Tên và bố cục opcode chính xác có thể thay đổi giữa các phiên bản.

## 37.21 Sao chép chủ đề

Chủ đề thường phải có sẵn trong khi thử nhiều trường hợp.```python
match value:
    case [x]:
        ...
    case {"x": x}:
        ...
    case _:
        ...
```Nếu trường hợp đầu tiên thất bại, trường hợp thứ hai vẫn cần chủ đề ban đầu.

Trình biên dịch phát ra các thao tác ngăn xếp để sao chép, bảo toàn hoặc loại bỏ chủ đề nếu cần.

Về mặt khái niệm:```text
subject on stack
try case 1
    if fail, restore subject
try case 2
    if fail, restore subject
fallback
```Kỷ luật ngăn xếp chính xác rất quan trọng vì việc khớp mẫu có nhiều đường dẫn lỗi.

## 37.22 Đường dẫn Thất bại

Một trường hợp có thể thất bại ở nhiều điểm:```text
wrong type
wrong sequence length
missing mapping key
class check fails
attribute extraction fails with AttributeError
nested subpattern fails
OR alternative fails
guard is false
```Một số lỗi là không khớp bình thường. Những người khác là ngoại lệ thực sự.

Việc so khớp mẫu phải phân biệt:```text
normal pattern failure
real runtime exception
```Ví dụ: khóa ánh xạ bị thiếu có nghĩa là mẫu ánh xạ không khớp.

Nhưng một người nhận tài sản làm tăng`RuntimeError`trong một mẫu lớp sẽ tuyên truyền ngoại lệ.

## 37.23 Bảo vệ và Ngoại lệ

Guard là mã Python thông thường.```python
match value:
    case x if check(x):
        ...
```Nếu như`check(x)`tăng lên, ngoại lệ lan truyền. Trình thông dịch không coi đó là một kết quả khớp không thành công.

Về mặt khái niệm:```text
pattern succeeds
evaluate guard
    returns true: select case
    returns false: try next case
    raises: propagate exception
```Điều này làm cho lính canh mạnh mẽ nhưng cũng hiệu quả.

## 37.24 Tra cứu khóa ánh xạ

Các mẫu ánh xạ sử dụng tra cứu khóa. Một mẫu như:```python
case {"name": name}:
```kiểm tra xem chủ đề có chứa khóa không`"name"`và rút ra giá trị của nó.

Việc triển khai phải tránh vô tình gọi ra hành vi làm thay đổi ngữ nghĩa so với các quy tắc mẫu ánh xạ.

Hành vi cấp nguồn quan trọng là:```text
required keys must exist
their values must match subpatterns
extra keys are allowed
```Nếu như`**rest`hiện diện, các cặp khóa-giá trị chưa khớp sẽ được sao chép vào từ điển mới.

## 37.25 Tra cứu thuộc tính mẫu lớp

Các mẫu lớp có thể thực hiện tra cứu thuộc tính.```python
case Point(x=x, y=y):
```Điều này có thể gọi:```text
Point-related descriptors
properties
__getattribute__
__getattr__
```Nếu quyền truy cập thuộc tính tăng lên`AttributeError`, mẫu lớp có thể bị lỗi do không khớp với thuộc tính đó. Các trường hợp ngoại lệ khác lan truyền.

Ví dụ:```python
class C:
    @property
    def x(self):
        raise RuntimeError("bad")

match C():
    case C(x=x):
        ...
```Điều này lan truyền`RuntimeError`.

## 37.26 Kết hợp mẫu và mô tả

Vì các mẫu lớp sử dụng quyền truy cập thuộc tính nên các bộ mô tả có thể tham gia.```python
class C:
    @property
    def x(self):
        return 10

match C():
    case C(x=10):
        result = "matched"
```Trình lấy thuộc tính chạy trong quá trình khớp.

Điều này có nghĩa là việc khớp mẫu có thể kích hoạt mã người dùng. Nó không phải lúc nào cũng là một cuộc kiểm tra kết cấu thụ động.

## 37.27 So khớp mẫu và các lớp dữ liệu

Các lớp dữ liệu hoạt động tự nhiên với các mẫu lớp.```python
from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int

def f(p):
    match p:
        case Point(0, y):
            return y
        case Point(x, y):
            return x + y
```Các lớp dữ liệu thường cung cấp`__match_args__`dựa trên các trường, do đó các mẫu lớp vị trí sẽ hoạt động.

Về mặt khái niệm:```text
Point(0, y)
    matches Point instance
    checks x == 0
    binds y from p.y
```## 37.28 So khớp mẫu và Enum

Enums thường được sử dụng với các mẫu giá trị.```python
from enum import Enum

class TokenKind(Enum):
    NAME = 1
    NUMBER = 2

match kind:
    case TokenKind.NAME:
        ...
    case TokenKind.NUMBER:
        ...
```Các tên có dấu chấm là các mẫu giá trị nên chúng so sánh với các thành viên enum hiện có.

Đừng viết:```python
case NAME:
```trừ khi bạn có ý định nắm bắt một biến mới.

## 37.29 So khớp mẫu và AST

Đối sánh mẫu rất hữu ích cho các cấu trúc dạng cây.```python
match node:
    case BinOp(left, "+", right):
        ...
    case Literal(value):
        ...
```Trình biên dịch hoặc trình thông dịch có thể sử dụng các mẫu lớp để kiểm tra các loại nút.

Ví dụ:```python
@dataclass
class Literal:
    value: object

@dataclass
class BinOp:
    left: object
    op: str
    right: object
```Sau đó:```python
match node:
    case BinOp(Literal(a), "+", Literal(b)):
        return Literal(a + b)
```Điều này thể hiện sự phân hủy cấu trúc một cách trực tiếp.

## 37.30 So khớp mẫu và ngăn xếp mã byte

So khớp mẫu sử dụng ngăn xếp giá trị khung giống như các mã byte khác.

Chủ đề, giá trị được trích xuất trung gian, kết quả so sánh và giá trị dự phòng được bảo toàn có thể nằm trong ngăn xếp.

Một mẫu trình tự:```python
case [x, y]:
```về mặt khái niệm thì:```text
subject
check sequence
check length
unpack two elements
store x
store y
execute body
```Nếu thất bại, các giá trị tạm thời sẽ được bật lên và trường hợp tiếp theo bắt đầu từ hình dạng ngăn xếp sạch.

## 37.31 Trách nhiệm của trình biên dịch

Trình biên dịch phải tạo mã byte để bảo toàn một số bất biến:```text
subject evaluated once
cases tried in order
successful pattern bindings visible in body
failed pattern bindings not relied on
guards evaluated after binding
guards can access bound names
stack shape valid at every jump
exceptions propagate correctly
only first successful case runs
```Do đó, khớp mẫu vừa là tính năng ngôn ngữ vừa là tính năng trình biên dịch.

## 37.32 Trách nhiệm trong thời gian chạy

Khi chạy, CPython phải thực hiện:```text
type checks
sequence checks
mapping checks
class checks
attribute extraction
key extraction
equality checks
binding
guard evaluation
failure jumps
exception propagation
```Một số thao tác này là các thao tác chung của Python và có thể gọi mã người dùng.

Ví dụ:```python
case SomeClass(x=x):
```có thể thực thi logic mô tả cho`x`.

```python
case 10:
```có thể sử dụng so sánh bình đẳng.

Việc khớp mẫu phải chính xác theo mô hình đối tượng động của Python.

## 37.33 Khớp mẫu và bình đẳng

Các mẫu chữ và giá trị có thể sử dụng sự bình đẳng.```python
case 10:
```phù hợp nếu chủ đề bằng`10`.

Đối với các đối tượng do người dùng định nghĩa, đẳng thức có thể gọi`__eq__`.

```python
class C:
    def __eq__(self, other):
        print("compare")
        return True

match C():
    case 10:
        print("matched")
```Điều này có thể thực thi mã người dùng.

Nếu đẳng thức tạo ra một ngoại lệ, ngoại lệ đó sẽ lan truyền.

## 37.34 Kết hợp mẫu và hiệu suất

Việc kết hợp mẫu có thể rõ ràng nhưng nó không phải là phép thuật. Nó vẫn thực hiện kiểm tra thời gian chạy.

Chi phí có thể bao gồm:```text
type checks
length checks
mapping lookups
attribute lookups
equality comparisons
temporary allocations
guard execution
bytecode branches
```Một cách đơn giản`if`chuỗi có thể nhanh hơn đối với các trường hợp vô hướng rất nhỏ.

Khớp mẫu hữu ích nhất khi cấu trúc có vấn đề:```text
nested data
AST nodes
protocol messages
token streams
configuration shapes
command parsing
event dispatch
```Sử dụng nó ở nơi nó cải thiện sự rõ ràng.

## 37.35 So khớp mẫu so với`if/elif`Cái này:```python
match value:
    case 0:
        ...
    case 1:
        ...
```có thể tương tự như:```python
if value == 0:
    ...
elif value == 1:
    ...
```Nhưng việc khớp mẫu còn đi xa hơn:```python
match value:
    case {"type": "user", "name": name}:
        ...
    case ["move", x, y]:
        ...
    case Point(x=0, y=y):
        ...
```Nó kết hợp các bài kiểm tra kiểu, kiểm tra hình dạng, giải nén và ràng buộc.

## 37.36 So khớp mẫu và phân tích cấu trúc

Nhiệm vụ hủy cấu trúc yêu cầu hình dạng phải khớp hoặc tăng lên.```python
x, y = value
```Nếu như`value`không có chính xác hai mục, nó sẽ tăng lên.

Các bài kiểm tra khớp mẫu có hình dạng và có thể vượt qua.```python
match value:
    case [x, y]:
        ...
    case _:
        ...
```Không khớp`[x, y]`chỉ cần thử trường hợp tiếp theo.

Vì vậy, khớp mẫu là phá hủy có điều kiện.

## 37.37 Đối sánh mẫu và phạm vi

Tên được ghi lại trong các mẫu là các ràng buộc cục bộ.```python
def f(value):
    match value:
        case x:
            return x
```Trình biên dịch xử lý`x`như địa phương để`f`.

Điều này có thể gây ngạc nhiên cho người dùng khi mong đợi sự so sánh với một biến bên ngoài.```python
expected = 10

def f(value):
    match value:
        case expected:
            return True
```Điều này ghi lại thành một tên địa phương`expected`. Nó không so sánh với bên ngoài`expected`.

Sử dụng:```python
def f(value):
    match value:
        case x if x == expected:
            return True
```hoặc sử dụng hằng số chấm.

## 37.38 Các trường hợp khớp mẫu và không thể truy cập

Một kiểu chụp nắm bắt mọi thứ.```python
match value:
    case x:
        ...
    case 0:
        ...
```Trường hợp thứ hai là không thể truy cập được.

Tương tự:```python
case _:
```vì trường hợp chưa phải là trường hợp cuối cùng khiến các trường hợp sau này không thể truy cập được.

Trình biên dịch phát hiện một số mẫu không thể bác bỏ ở các vị trí không hợp lệ.

Một mẫu không thể bác bỏ là một mẫu luôn phù hợp, chẳng hạn như:```text
_
x
object()
```trong nhiều bối cảnh.

## 37.39 Khớp mẫu và`object()`Một mẫu lớp không có đối số có thể khớp với bất kỳ phiên bản nào của lớp đó.```python
case object():
```Vì gần như tất cả các đối tượng bình thường đều là những thể hiện của`object`, điều này hoàn toàn phù hợp.

Nó khác với:```python
case object:
```đó là một mẫu chụp có tên`object`, trừ khi cú pháp được giải quyết khác nhau thông qua ngữ cảnh. Tránh đặt tên mơ hồ trong các mẫu.

## 37.40 Khớp mẫu và`None`Để phù hợp`None`, sử dụng:```python
case None:
```Đây là một mẫu đơn theo nghĩa đen.

Không sử dụng:```python
case x:
```và mong đợi nó so sánh với bên ngoài`x`.

Mẫu đơn cho`None`, `True`, Và`False`là phổ biến và rõ ràng.

## 37.41 So khớp mẫu và bảo mật

Khớp mẫu có thể thực thi mã người dùng.

Các điểm thực hiện tiềm năng bao gồm:```text
equality comparison
attribute access
descriptor access
mapping methods
sequence methods
guard expressions
```Đối với các đối tượng trong bộ nhớ đáng tin cậy, điều này là bình thường.

Đối với các đối tượng không đáng tin cậy có phương thức thù địch, việc khớp mẫu phải được xử lý giống như thực thi Python thông thường, không phải là truy vấn khai báo an toàn.

## 37.42 Kiểm tra việc khớp mẫu

sử dụng`dis`để kiểm tra mã byte phù hợp.```python
import dis

def f(value):
    match value:
        case [x, y]:
            return x + y
        case {"x": x}:
            return x
        case _:
            return 0

dis.dis(f)
```Hãy tìm:```text
subject handling
pattern-specific checks
unpack operations
mapping operations
jumps between cases
stores for captured names
guard evaluation
return paths
```Mã byte chính xác thay đổi trên các phiên bản Python.

## 37.43 Công cụ so khớp mẫu tối thiểu

Một công cụ so khớp cấu trúc nhỏ cho danh sách có thể thể hiện ý tưởng.```python
def match_pair(value):
    if isinstance(value, (list, tuple)) and len(value) == 2:
        x, y = value
        return True, {"x": x, "y": y}
    return False, {}
```Sử dụng:```python
ok, binds = match_pair([1, 2])
if ok:
    print(binds["x"] + binds["y"])
```Điều này phản ánh một phần nhỏ của:```python
match value:
    case [x, y]:
        print(x + y)
```CPython thực hiện điều này thông qua mã byte được biên dịch và trình trợ giúp thời gian chạy thay vì từ điển các ràng buộc.

## 37.44 Những hiểu lầm phổ biến

| Hiểu lầm | Đúng mẫu |
|---|---|
|`match`chỉ là một câu lệnh switch | Nó thực hiện khớp cấu trúc và liên kết |
|`case x`so sánh với biến`x`| Nó nắm bắt chủ đề vào`x` |
| `_`là chụp bình thường |`_`là ký tự đại diện trong mẫu |
| Chủ đề được đánh giá cho mọi trường hợp | Nó được đánh giá một lần |
| Việc khớp mẫu không có tác dụng phụ | Nó có thể gọi đẳng thức, bộ mô tả, bộ bảo vệ và móc thuộc tính |
| Trận đấu thất bại là ngoại lệ | Lỗi mẫu thông thường sẽ chuyển sang trường hợp tiếp theo |
| Các mẫu lớp kiểm tra các trường trực tiếp | Họ sử dụng quyền truy cập thuộc tính và`__match_args__`|
| Khớp mẫu luôn nhanh hơn`if`| Nó vẫn thực hiện kiểm tra thời gian chạy |

## 37,45 Chiến lược đọc

Bắt đầu với trường hợp vô hướng:```python
def f(x):
    match x:
        case 0:
            return "zero"
        case _:
            return "other"
```Sau đó thêm cấu trúc:```python
def f(x):
    match x:
        case [a, b]:
            return a + b
        case {"name": name}:
            return name
```Sau đó thêm các lớp:```python
class Point:
    __match_args__ = ("x", "y")

def f(p):
    match p:
        case Point(0, y):
            return y
        case Point(x, y):
            return x + y
```Đối với mỗi phiên bản:```python
import dis
dis.dis(f)
```Theo dõi:```text
where the subject is stored
where each case begins
which checks can fail normally
which operations can raise
where names are bound
where guards run
where fallback jumps go
```## 37.46 Tóm tắt chương

Khớp mẫu là hệ thống điều phối có điều kiện cấu trúc của CPython. Nó đánh giá một chủ đề một lần, thử các trường hợp theo thứ tự, kiểm tra các mẫu, liên kết tên, đánh giá các lính canh và thực thi phần thân phù hợp đầu tiên.

Mô hình cốt lõi là:

```văn bản
đánh giá chủ đề một lần
    ↓
thử mẫu trường hợp
    ↓
nếu mẫu không thành công: dọn dẹp và thử trường hợp tiếp theo
    ↓
nếu mẫu thành công: liên kết tên
    ↓
nếu bảo vệ tồn tại: đánh giá bảo vệ
    ↓
nếu bảo vệ đúng hoặc vắng mặt: thực thi phần thân