Hướng dẫn what is pattern matching in python? - đối sánh mẫu trong python là gì?

Tác giả: Daniel F Moisset Nhà tài trợ: Guido Van Rossum BDFL-DEGATE: Thảo luận-To: Python-Dev Liststatus: FinalType: InformationalCreated: 12-SEP-2020 2021Resolution: Tin nhắn Python-Committers:Daniel F Moisset Sponsor:Guido van Rossum BDFL-Delegate:Discussions-To:Python-Dev listStatus:FinalType:InformationalCreated: 12-Sep-2020Python-Version:3.10Post-History:22-Oct-2020, 08-Feb-2021Resolution:Python-Committers message
Mục lục
  • trừu tượng
  • Hướng dẫn
    • Trình tự phù hợp
    • Phù hợp với nhiều mẫu
    • Phù hợp với các giá trị cụ thể
    • Phù hợp với nhiều giá trị
    • Thêm một ký tự đại diện
    • Bán các mẫu
    • Hoặc các mẫu
    • Nắm bắt các mẫu phụ phù hợp
    • Thêm điều kiện vào các mẫu
    • Thêm UI: Đối tượng phù hợp
    • Phù hợp với các thuộc tính vị trí
    • Phù hợp với các hằng số và enums
    • Đi đến đám mây: ánh xạ
    • Phù hợp với các lớp học tích hợp
  • Phụ lục A - Giới thiệu nhanh
  • Bản quyền

trừu tượng

Hướng dẫn

Trình tự phù hợp

Phù hợp với nhiều mẫu

Phù hợp với các giá trị cụ thể

Hướng dẫn

Trình tự phù hợp

Trình tự phù hợp

Phù hợp với nhiều mẫu

command = input("What are you doing next? ") # analyze the result of command.split()

Phù hợp với các giá trị cụ thể

[action, obj] = command.split() ... # interpret action, obj

Phù hợp với nhiều giá trị

Thêm một ký tự đại diện

match command.split(): case [action, obj]: ... # interpret action, obj

Bán các mẫu“subject” (the value after the match command.split(): case [action]: ... # interpret single-verb action case [action, obj]: ... # interpret action, obj 3 keyword), and checks it against the pattern (the code next to match command.split(): case [action]: ... # interpret single-verb action case [action, obj]: ... # interpret action, obj 4). A pattern is able to do two different things:

  • Hoặc các mẫumatching
  • Nắm bắt các mẫu phụ phù hợp

Thêm điều kiện vào các mẫu

Thêm UI: Đối tượng phù hợp

Phù hợp với nhiều mẫu

Phù hợp với các giá trị cụ thể

match command.split(): case [action]: ... # interpret single-verb action case [action, obj]: ... # interpret action, obj

Phù hợp với nhiều giá trị

Phù hợp với các giá trị cụ thể

Phù hợp với nhiều giá trị

match command.split(): case ["quit"]: print("Goodbye!") quit_game() case ["look"]: current_room.describe() case ["get", obj]: character.get(obj, current_room) case ["go", direction]: current_room = current_room.neighbor(direction) # The rest of your commands go here

Thêm một ký tự đại diện

Như bạn có thể thấy trong trường hợp match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here 5, chúng tôi cũng có thể sử dụng các tên biến khác nhau trong các mẫu khác nhau.

Các giá trị theo nghĩa đen được so sánh với toán tử match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here 6 ngoại trừ các hằng số match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here 7, match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here 8 và match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here 1 được so sánh với toán tử match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 0.

Phù hợp với nhiều giá trị

Người chơi có thể bỏ nhiều mục bằng cách sử dụng một loạt các lệnh match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 1, match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 2, match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 3. Giao diện này có thể cồng kềnh và bạn có thể muốn cho phép bỏ nhiều mục trong một lệnh duy nhất, như match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 4. Trong trường hợp này, bạn không biết trước có bao nhiêu từ trong lệnh, nhưng bạn có thể sử dụng việc giải nén mở rộng trong các mẫu giống như cách chúng được phép trong các bài tập:

match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here

Điều này sẽ phù hợp với bất kỳ trình tự nào có các loại Drop Drop như các yếu tố đầu tiên của nó. Tất cả các phần tử còn lại sẽ được ghi lại trong một đối tượng match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 5 sẽ được liên kết với biến match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 6.

Cú pháp này có các hạn chế tương tự như việc giải nén trình tự: bạn không thể có nhiều hơn một tên được đặt tên trong một mẫu.

Thêm một ký tự đại diện

Bạn có thể muốn in một thông báo lỗi nói rằng lệnh đã được nhận ra khi tất cả các mẫu đều thất bại. Bạn có thể sử dụng tính năng mà chúng tôi vừa học và viết match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 7 làm mẫu cuối cùng của bạn. Tuy nhiên, có một cách đơn giản hơn nhiều:

match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}")

Mẫu đặc biệt này được viết match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 8 (và được gọi là ký tự đại diện) luôn phù hợp nhưng nó không liên kết bất kỳ biến nào.

Lưu ý rằng điều này sẽ phù hợp với bất kỳ đối tượng, không chỉ các chuỗi. Như vậy, nó chỉ có ý nghĩa khi tự nó làm mẫu cuối cùng (để ngăn chặn lỗi, Python sẽ ngăn bạn sử dụng nó trước đây).

Bán các mẫu

Đây là một khoảnh khắc tốt để lùi lại từ các ví dụ và hiểu làm thế nào các mẫu mà bạn đã sử dụng được xây dựng. Các mẫu có thể được lồng trong nhau và chúng tôi đã làm điều đó một cách ngầm định trong các ví dụ trên.

Có một số mẫu đơn giản của người Viking (ở đây, đơn giản ở đây có nghĩa là chúng không chứa các mẫu khác) mà chúng tôi đã thấy:

  • Các mẫu chụp (tên độc lập như match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 9, match command.split(): ... # Other cases case ["north"] | ["go", "north"]: current_room = current_room.neighbor("north") case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]: ... # Code for picking up the given object 0, match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 6). Chúng tôi không bao giờ thảo luận riêng này, nhưng sử dụng chúng như một phần của các mẫu khác. (stand-alone names like match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 9, match command.split(): ... # Other cases case ["north"] | ["go", "north"]: current_room = current_room.neighbor("north") case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]: ... # Code for picking up the given object 0, match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 6). We never discussed these separately, but used them as part of other patterns.
  • Các mẫu theo nghĩa đen (Chuỗi chữ, chữ số, match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here 7, match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here 8 và match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here 1) (string literals, number literals, match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here 7, match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here 8, and match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here 1)
  • Mô hình ký tự đại diện match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 8wildcard pattern match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 8

Cho đến nay, mẫu không đơn giản duy nhất mà chúng tôi đã thử nghiệm là mẫu trình tự. Mỗi yếu tố trong một mẫu trình tự trên thực tế có thể là bất kỳ mẫu nào khác. Điều này có nghĩa là bạn có thể viết một mẫu như match command.split(): ... # Other cases case ["north"] | ["go", "north"]: current_room = current_room.neighbor("north") case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]: ... # Code for picking up the given object 6. Điều này sẽ phù hợp với các đối tượng là một chuỗi ít nhất ba phần tử, trong đó cái đầu tiên bằng match command.split(): ... # Other cases case ["north"] | ["go", "north"]: current_room = current_room.neighbor("north") case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]: ... # Code for picking up the given object 7 và phần thứ hai lần lượt một chuỗi gồm hai yếu tố. Nó cũng sẽ liên kết match command.split(): ... # Other cases case ["north"] | ["go", "north"]: current_room = current_room.neighbor("north") case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]: ... # Code for picking up the given object 8, match command.split(): ... # Other cases case ["north"] | ["go", "north"]: current_room = current_room.neighbor("north") case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]: ... # Code for picking up the given object 9 và match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go? 0

Hoặc các mẫu

Quay trở lại ví dụ về trò chơi phiêu lưu, bạn có thể thấy rằng bạn muốn có một số mẫu dẫn đến kết quả tương tự. Ví dụ: bạn có thể muốn các lệnh match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go? 1 và match command.split(): case [action, obj]: ... # interpret action, obj 9 tương đương. Bạn cũng có thể mong muốn có bí danh cho match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go? 3, match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go? 4 và match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go? 5 cho bất kỳ X.

Biểu tượng match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go? 6 trong các mẫu kết hợp chúng như các lựa chọn thay thế. Ví dụ, bạn có thể viết:

match command.split(): ... # Other cases case ["north"] | ["go", "north"]: current_room = current_room.neighbor("north") case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]: ... # Code for picking up the given object

Điều này được gọi là một hoặc mẫu và sẽ tạo ra kết quả dự kiến. Các mẫu được thử từ trái sang phải; Điều này có thể có liên quan để biết những gì bị ràng buộc nếu có nhiều hơn một trận đấu thay thế. Một hạn chế quan trọng khi viết hoặc mẫu là tất cả các lựa chọn thay thế nên liên kết cùng một biến. Vì vậy, một mẫu match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go? 7 không được phép vì nó sẽ không rõ biến nào sẽ bị ràng buộc sau một trận đấu thành công. match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go? 8 hoàn toàn tốt và sẽ luôn ràng buộc match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go? 9 nếu thành công.or pattern and will produce the expected result. Patterns are tried from left to right; this may be relevant to know what is bound if more than one alternative matches. An important restriction when writing or patterns is that all alternatives should bind the same variables. So a pattern match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go? 7 is not allowed because it would make unclear which variable would be bound after a successful match. match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go? 8 is perfectly fine and will always bind match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go? 9 if successful.

Nắm bắt các mẫu phụ phù hợp

Phiên bản đầu tiên của lệnh Go Go của chúng tôi được viết với mẫu match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 0. Sự thay đổi chúng tôi đã thực hiện trong phiên bản cuối cùng của chúng tôi bằng cách sử dụng mẫu match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 1 có một số lợi ích nhưng cũng có một số nhược điểm trong so sánh: phiên bản mới nhất cho phép bí danh, nhưng cũng có hướng được mã hóa cứng, điều này sẽ buộc chúng tôi thực sự có các mẫu riêng cho Bắc/Nam/ Đông Tây. Điều này dẫn đến một số sao chép mã, nhưng đồng thời chúng tôi nhận được xác thực đầu vào tốt hơn và chúng tôi sẽ không vào chi nhánh đó nếu lệnh được người dùng nhập vào là match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 2 thay vì hướng.

Chúng ta có thể cố gắng để có được những điều tốt nhất của cả hai thế giới khi làm như sau (tôi sẽ bỏ qua phiên bản bí danh mà không có Go Go cho sự ngắn gọn):

match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go?

Mã này là một nhánh duy nhất và nó xác minh rằng từ sau khi Go Go thực sự là một hướng. Nhưng mã di chuyển người chơi xung quanh cần biết cái nào được chọn và không có cách nào để làm điều đó. Những gì chúng ta cần là một mô hình hoạt động giống như hoặc mẫu nhưng đồng thời bắt giữ. Chúng ta có thể làm như vậy với một mẫu AS:as pattern:

match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction)

Các mẫu AS phù hợp với bất kỳ mẫu nào ở phía bên trái của nó, nhưng cũng liên kết giá trị với một cái tên.

Thêm điều kiện vào các mẫu

Các mẫu chúng tôi đã khám phá ở trên có thể thực hiện một số bộ lọc dữ liệu mạnh mẽ, nhưng đôi khi bạn có thể mong muốn toàn bộ sức mạnh của biểu thức Boolean. Hãy để nói rằng bạn thực sự muốn cho phép một lệnh Go Go chỉ trong một bộ hướng dẫn bị hạn chế dựa trên các lối thoát có thể từ current_room. Chúng tôi có thể đạt được điều đó bằng cách thêm một người bảo vệ vào trường hợp của chúng tôi. Guard bao gồm từ khóa match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 3 theo sau là bất kỳ biểu thức nào:guard to our case. Guards consist of the match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 3 keyword followed by any expression:

[action, obj] = command.split() ... # interpret action, obj 0

Người bảo vệ không phải là một phần của mô hình, nó là một phần của vụ án. Nó chỉ kiểm tra xem mẫu có khớp hay không và sau tất cả các biến mẫu đã bị ràng buộc (đó là lý do tại sao điều kiện có thể sử dụng biến match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 9 trong ví dụ trên). Nếu mẫu phù hợp và điều kiện là sự thật, thì cơ thể của vụ án sẽ thực hiện bình thường. Nếu mẫu phù hợp nhưng điều kiện là giả, câu lệnh Match tiến hành kiểm tra trường hợp tiếp theo như thể mẫu đã không khớp (với hiệu ứng phụ có thể đã ràng buộc một số biến).

Thêm UI: Đối tượng phù hợp

Cuộc phiêu lưu của bạn đang trở thành một thành công và bạn đã được yêu cầu thực hiện giao diện đồ họa. Bộ công cụ UI của bạn lựa chọn cho phép bạn viết một vòng lặp sự kiện nơi bạn có thể nhận được một đối tượng sự kiện mới bằng cách gọi match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 5. Đối tượng kết quả có thể có loại và thuộc tính khác nhau theo hành động của người dùng, ví dụ:

  • Đối tượng match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 6 được tạo khi người dùng nhấn phím. Nó có thuộc tính match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 7 với tên của khóa được nhấn và một số thuộc tính khác liên quan đến các công cụ sửa đổi.
  • Đối tượng match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 8 được tạo khi người dùng nhấp chuột. Nó có một thuộc tính match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 9 với tọa độ của con trỏ.
  • Đối tượng [action, obj] = command.split() ... # interpret action, obj 00 được tạo khi người dùng nhấp vào nút Đóng cho cửa sổ trò chơi.

Thay vì viết nhiều kiểm tra [action, obj] = command.split() ... # interpret action, obj 01, bạn có thể sử dụng các mẫu để nhận ra các loại đối tượng khác nhau và cũng áp dụng các mẫu cho các thuộc tính của nó:

[action, obj] = command.split() ... # interpret action, obj 1

Một mẫu như [action, obj] = command.split() ... # interpret action, obj 02 chỉ khớp với loại sự kiện là một lớp con của lớp match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 8. Nó cũng sẽ yêu cầu sự kiện này có thuộc tính match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 9 phù hợp với mẫu [action, obj] = command.split() ... # interpret action, obj 05. Nếu có một trận đấu, người dân địa phương match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go? 9 và [action, obj] = command.split() ... # interpret action, obj 07 sẽ nhận được các giá trị dự kiến.

Một mẫu như [action, obj] = command.split() ... # interpret action, obj 08, không có đối số nào sẽ phù hợp với bất kỳ đối tượng nào là một thể hiện của lớp match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 6. Chỉ các thuộc tính bạn chỉ định trong mẫu được khớp và bất kỳ thuộc tính nào khác đều bị bỏ qua.

Phù hợp với các thuộc tính vị trí

Phần trước đã mô tả cách khớp với các thuộc tính được đặt tên khi thực hiện khớp đối tượng. Đối với một số đối tượng, có thể thuận tiện để mô tả các đối số phù hợp theo vị trí (đặc biệt là nếu chỉ có một vài thuộc tính và chúng có thứ tự tiêu chuẩn của người Hồi giáo). Nếu các lớp mà bạn đang sử dụng có tên là Tuples hoặc DataClasses, bạn có thể làm điều đó bằng cách tuân theo cùng một thứ tự mà bạn đã sử dụng khi xây dựng một đối tượng. Ví dụ: nếu khung UI ở trên định nghĩa lớp của họ như thế này:

[action, obj] = command.split() ... # interpret action, obj 2

Sau đó, bạn có thể viết lại câu lệnh khớp của mình ở trên như:

[action, obj] = command.split() ... # interpret action, obj 3

Mẫu [action, obj] = command.split() ... # interpret action, obj 05 sẽ tự động khớp với thuộc tính match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 9, bởi vì đối số đầu tiên trong mẫu tương ứng với thuộc tính đầu tiên trong định nghĩa DataClass của bạn.

Các lớp khác không có thứ tự tự nhiên các thuộc tính của chúng, vì vậy bạn cần phải sử dụng tên rõ ràng trong mẫu của bạn để phù hợp với các thuộc tính của chúng. Tuy nhiên, nó có thể chỉ định thủ công thứ tự của các thuộc tính cho phép khớp vị trí, như trong định nghĩa thay thế này:

[action, obj] = command.split() ... # interpret action, obj 4

Thuộc tính đặc biệt [action, obj] = command.split() ... # interpret action, obj 12 xác định một thứ tự rõ ràng cho các thuộc tính của bạn có thể được sử dụng trong các mẫu như [action, obj] = command.split() ... # interpret action, obj 13.

Phù hợp với các hằng số và enums

Mẫu của bạn ở trên xử lý tất cả các nút chuột giống nhau và bạn đã quyết định rằng bạn muốn chấp nhận nhấp chuột trái và bỏ qua các nút khác. Trong khi làm như vậy, bạn nhận thấy rằng thuộc tính [action, obj] = command.split() ... # interpret action, obj 14 được gõ dưới dạng [action, obj] = command.split() ... # interpret action, obj 15 là một bảng liệt kê được xây dựng với [action, obj] = command.split() ... # interpret action, obj 16. Trên thực tế, bạn có thể khớp với các giá trị liệt kê như thế này:

[action, obj] = command.split() ... # interpret action, obj 5

Điều này sẽ hoạt động với bất kỳ tên chấm chấm (như [action, obj] = command.split() ... # interpret action, obj 17). Tuy nhiên, một tên không đủ tiêu chuẩn (nghĩa là một tên trần không có dấu chấm) sẽ luôn được hiểu là một mẫu chụp, vì vậy hãy tránh sự mơ hồ đó bằng cách luôn sử dụng các hằng số đủ điều kiện trong các mẫu.

Đi đến đám mây: ánh xạ

Bạn đã quyết định tạo một phiên bản trực tuyến của trò chơi của bạn. Tất cả logic của bạn sẽ ở trong một máy chủ và giao diện người dùng trong một máy khách sẽ liên lạc bằng tin nhắn JSON. Thông qua mô -đun [action, obj] = command.split() ... # interpret action, obj 18, chúng sẽ được ánh xạ tới từ điển Python, danh sách và các đối tượng tích hợp khác.

Khách hàng của chúng tôi sẽ nhận được một danh sách các từ điển (được phân tích cú pháp từ JSON) các hành động cần thực hiện, mỗi yếu tố tìm kiếm ví dụ như sau:

  • [action, obj] = command.split() ... # interpret action, obj 19
  • Nếu khách hàng nên tạm dừng [action, obj] = command.split() ... # interpret action, obj 20
  • Để phát một âm thanh [action, obj] = command.split() ... # interpret action, obj 21

Cho đến bây giờ, các mẫu của chúng tôi có trình tự được xử lý, nhưng có các mẫu để phù hợp với ánh xạ dựa trên các khóa hiện tại của chúng. Trong trường hợp này bạn có thể sử dụng:

[action, obj] = command.split() ... # interpret action, obj 6

Các khóa trong mẫu ánh xạ của bạn cần phải là nghĩa đen, nhưng các giá trị có thể là bất kỳ mẫu nào. Như trong các mẫu trình tự, tất cả các mẫu con phải khớp với mẫu chung để khớp.

Bạn có thể sử dụng [action, obj] = command.split() ... # interpret action, obj 22 trong mẫu ánh xạ để chụp các khóa bổ sung trong chủ đề. Lưu ý rằng nếu bạn bỏ qua điều này, các khóa phụ trong chủ đề sẽ bị bỏ qua trong khi khớp, tức là thông báo [action, obj] = command.split() ... # interpret action, obj 23 sẽ khớp với mẫu đầu tiên trong ví dụ trên.

Phù hợp với các lớp học tích hợp

Mã trên có thể sử dụng một số xác nhận. Cho rằng các thông điệp đến từ một nguồn bên ngoài, các loại trường có thể sai, dẫn đến lỗi hoặc các vấn đề bảo mật.

Bất kỳ lớp nào là mục tiêu khớp hợp lệ và bao gồm các lớp tích hợp như [action, obj] = command.split() ... # interpret action, obj 24 [action, obj] = command.split() ... # interpret action, obj 25 hoặc [action, obj] = command.split() ... # interpret action, obj 26. Điều đó cho phép chúng tôi kết hợp mã trên với một mẫu lớp. Vì vậy, thay vì viết [action, obj] = command.split() ... # interpret action, obj 27, chúng ta có thể sử dụng [action, obj] = command.split() ... # interpret action, obj 28 để đảm bảo rằng [action, obj] = command.split() ... # interpret action, obj 29 và [action, obj] = command.split() ... # interpret action, obj 30 đều là cả hai chuỗi. Đối với nhiều lớp tích hợp (xem PEP 634 cho toàn bộ danh sách), bạn có thể sử dụng tham số vị trí làm tốc ký, viết [action, obj] = command.split() ... # interpret action, obj 31 thay vì [action, obj] = command.split() ... # interpret action, obj 32. Phiên bản viết lại đầy đủ trông như thế này:

[action, obj] = command.split() ... # interpret action, obj 7

Phụ lục A - Giới thiệu nhanh

Một câu lệnh Match có một biểu thức và so sánh giá trị của nó với các mẫu liên tiếp được đưa ra dưới dạng một hoặc nhiều khối trường hợp. Điều này tương tự hời hợt với một câu lệnh chuyển đổi trong C, Java hoặc JavaScript (và nhiều ngôn ngữ khác), nhưng mạnh mẽ hơn nhiều.

Hình thức đơn giản nhất so sánh giá trị chủ đề với một hoặc nhiều chữ:

[action, obj] = command.split() ... # interpret action, obj 8

Lưu ý Khối cuối cùng: Tên biến có thể thay đổi match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 8 hoạt động như một ký tự đại diện và không bao giờ thất bại để phù hợp.

Bạn có thể kết hợp một số chữ theo một mẫu bằng cách sử dụng match command.split(): case ["go", ("north" | "south" | "east" | "west")]: current_room = current_room.neighbor(...) # how do I know which direction to go? 6 (về hoặc hoặc):

[action, obj] = command.split() ... # interpret action, obj 9

Các mẫu có thể trông giống như các bài tập giải nén và có thể được sử dụng để liên kết các biến:

match command.split(): case [action, obj]: ... # interpret action, obj 0

Nghiên cứu một cách cẩn thận! Mẫu đầu tiên có hai chữ, và có thể được coi là một phần mở rộng của mẫu theo nghĩa đen được hiển thị ở trên. Nhưng hai mẫu tiếp theo kết hợp một nghĩa đen và một biến, và biến liên kết một giá trị từ đối tượng ([action, obj] = command.split() ... # interpret action, obj 35). Mẫu thứ tư nắm bắt hai giá trị, làm cho nó tương tự về mặt khái niệm với gán giải nén [action, obj] = command.split() ... # interpret action, obj 36.

Nếu bạn đang sử dụng các lớp để cấu trúc dữ liệu của mình, bạn có thể sử dụng tên lớp theo sau là danh sách đối số giống như một hàm tạo, nhưng với khả năng nắm bắt các thuộc tính thành các biến:

match command.split(): case [action, obj]: ... # interpret action, obj 1

Bạn có thể sử dụng các tham số vị trí với một số lớp tích hợp cung cấp đặt hàng cho các thuộc tính của chúng (ví dụ: DataClasses). Bạn cũng có thể xác định một vị trí cụ thể cho các thuộc tính trong các mẫu bằng cách đặt thuộc tính đặc biệt [action, obj] = command.split() ... # interpret action, obj 12 trong các lớp của bạn. Nếu nó được đặt thành ((X X,

match command.split(): case [action, obj]: ... # interpret action, obj 2

Các mẫu có thể được lồng tùy ý. Ví dụ: nếu chúng ta có một danh sách ngắn các điểm, chúng ta có thể khớp nó như thế này:

match command.split(): case [action, obj]: ... # interpret action, obj 3

Chúng ta có thể thêm một điều khoản match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction) 3 vào một mẫu, được gọi là một người bảo vệ. Nếu người bảo vệ sai, match command.split(): case [action]: ... # interpret single-verb action case [action, obj]: ... # interpret action, obj 3 tiếp tục thử khối trường hợp tiếp theo. Lưu ý rằng việc bắt giá trị xảy ra trước khi người bảo vệ được đánh giá:

match command.split(): case [action, obj]: ... # interpret action, obj 4

Một số tính năng chính khác:

  • Giống như giải nén các bài tập, các mẫu Tuple và List có cùng một ý nghĩa và thực sự phù hợp với các chuỗi tùy ý. Một ngoại lệ quan trọng là họ không phù hợp với trình lặp hoặc dây. (Về mặt kỹ thuật, đối tượng phải là một ví dụ của [action, obj] = command.split() ... # interpret action, obj 42.)
  • Các mẫu trình tự hỗ trợ ký tự đại diện: [action, obj] = command.split() ... # interpret action, obj 43 và [action, obj] = command.split() ... # interpret action, obj 44 hoạt động tương tự như các ký tự đại diện trong việc giải nén các bài tập. Tên sau [action, obj] = command.split() ... # interpret action, obj 45 cũng có thể là match command.split(): case ["quit"]: ... # Code omitted for brevity case ["go", direction]: ... case ["drop", *objects]: ... ... # Other cases case _: print(f"Sorry, I couldn't understand {command!r}") 8, do đó [action, obj] = command.split() ... # interpret action, obj 47 khớp với một chuỗi ít nhất hai mục mà không ràng buộc các mục còn lại.
  • Các mẫu ánh xạ: [action, obj] = command.split() ... # interpret action, obj 48 nắm bắt các giá trị [action, obj] = command.split() ... # interpret action, obj 49 và [action, obj] = command.split() ... # interpret action, obj 50 từ một dict. Không giống như các mẫu trình tự, các khóa phụ bị bỏ qua. Một ký tự đại diện [action, obj] = command.split() ... # interpret action, obj 22 cũng được hỗ trợ. (Nhưng [action, obj] = command.split() ... # interpret action, obj 52 sẽ dư thừa, vì vậy nó không được phép.)
  • Tiểu nhà có thể được ghi lại bằng từ khóa [action, obj] = command.split() ... # interpret action, obj 53:

    match command.split(): case [action, obj]: ... # interpret action, obj 5

  • Hầu hết các chữ được so sánh bằng sự bình đẳng, tuy nhiên các singletons match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here 7, match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here 8 và match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room) # The rest of your commands go here 1 được so sánh bằng danh tính.
  • Các mẫu có thể sử dụng hằng số được đặt tên. Đây phải là những cái tên chấm để ngăn chúng được hiểu là biến bắt giữ:

    match command.split(): case [action, obj]: ... # interpret action, obj 6

Bản quyền

Tài liệu này được đặt trong phạm vi công cộng hoặc theo giấy phép CC0-1.0-Universal, tùy theo điều kiện nào cho phép hơn.

Phù hợp với mẫu là gì giải thích?

Trong khoa học máy tính, kết hợp mô hình là hành động kiểm tra một chuỗi mã thông báo nhất định cho sự hiện diện của các thành phần của một số mẫu.the act of checking a given sequence of tokens for the presence of the constituents of some pattern.

Phù hợp với mẫu là gì cho một ví dụ?

Ví dụ: x* khớp với bất kỳ số lượng ký tự x nào, [0-9]* khớp với bất kỳ số chữ số nào và.* Khớp với bất kỳ số lượng nào.Một mẫu biểu thức thông thường khớp thành công nếu mẫu khớp với bất cứ nơi nào trong giá trị đang được kiểm tra.x* matches any number of x characters, [0-9]* matches any number of digits, and . * matches any number of anything. A regular expression pattern match succeeds if the pattern matches anywhere in the value being tested.

Cú pháp khớp mẫu là gì?

Ngôn ngữ.Kết hợp mẫu là một cơ chế để kiểm tra giá trị so với một mẫu.Một trận đấu thành công cũng có thể giải mã một giá trị thành các phần cấu thành của nó.Đây là một phiên bản mạnh mẽ hơn của câu lệnh Switch trong Java và nó cũng có thể được sử dụng thay cho một loạt các câu lệnh IF/ELSE.a mechanism for checking a value against a pattern. A successful match can also deconstruct a value into its constituent parts. It is a more powerful version of the switch statement in Java and it can likewise be used in place of a series of if/else statements.

Chủ đề