Python 重大變化:是 match-case,不是 switch-case
有很多人期待在 Python 中使用 switch-case 語句,Python 社區裏針對它有過長達數年的討論(PEP-275、PEP-3103),然而結論是不支持。最近,官方終於通過了 PEP,Python 將要迎來一次重大更新!match-case 與 switch-case 的結構相似,然而其思想與用途有着巨大差別。有人喜歡,有人憎惡。今天分享一篇文章,讓大家見識一下這個新東西到底有什麼本事。
前言
2021 年 2 月 8 日,指導委員會通過了 PEP 634, PEP635, PEP636,至此,Python 總算擁有了 match-case, 不用再寫一連串的 if-else 了
嘿餵狗
1
最簡單的形式如下,將 match 主題表達式與一個或多個字面量模式進行比較
1def http_error(status):
2 match status:
3 case 400:
4 return "Bad request"
5 case 401:
6 return "Unauthorized"
7 case 403:
8 return "Forbidden"
9 case 404:
10 return "Not found"
11 case 418:
12 return "I'm a teapot"
13 case _:
14 return "Something else"
15
最後一個 case 中,case _:
類似於 C 和 Java 中的default:
,永遠不會匹配失敗,即當其他 case 都無法匹配時,匹配這條
2
可以使用|
將多個字面量組合起來表示或
1...
2 case 401|403|404:
3 return "Not allowed"
4
5
3
模式也可以是解包操作,用於綁定變量
1# 主題表達式是一個(x, y)元組
2match point:
3 case (0, 0):
4 print("Origin")
5 case (0, y):
6 print(f"Y={y}")
7 case (x, 0):
8 print(f"X={x}")
9 case (x, y):
10 print(f"X={x}, Y={y}")
11 case _:
12 raise ValueError("Not a point")
13
14
注意,第一個模式中有兩個字面量,可以看作是上述普通模式的加強版。但是後兩個模式有些不同,元組中一個是字面量一個是變量,這個變量會捕獲主題元組中的值。同理,第四個模式case (x, y):
會捕獲兩個值,這在理論上與解包作業相似,就如同point(x, y) = point
4
如果使用了結構數據類,比如data classes
,可以用類似於構造函數'類名 + 參數列表'的形式,但是用來捕獲變量
1from dataclasses import dataclass
2
3 @dataclass
4class Point:
5 x: int
6 y: int
7
8 def whereis(point):
9 match point:
10 case Point(0, 0):
11 print("Origin")
12 case Point(0, y):
13 print(f"Y={y}")
14 case Point(x, 0):
15 print(f"X={x}")
16 case Point():
17 print("Somewhere else")
18 case _:
19 print("Not a point")
20
5
也可以使用關鍵字參數。下列關於y, var
的模式都是等價的,並且都將屬性綁定到了變量上
1Point(1, var)
2Point(1, y=var)
3Point(x=1, y=var)
4Point(y=var, x=1)
5
6
6
模式可以被簡單粗暴的嵌套起來,例如我們有一組 points 的列表,就可以像這樣匹配
1match points:
2 case []:
3 print("No points")
4 case [Point(0, 0)]:
5 print("The origin")
6 case [Point(x, y)]:
7 print(f"Single point {x}, {y}")
8 case [Point(0, y1), Point(0, y2)]:
9 print(f"Two on the Y axis at {y1}, {y2}")
10 case _:
11 print("Something else")
12
13
7
給模式添加 if 從句以充當門衛。如果爲假,就移步到下一個 case。注意,模式捕獲值發生在從句執行前
1match point:
2 case Point(x, y) if x == y:
3 print(f"Y=X at {x}")
4 case Point(x, y):
5 print(f"Not on the diagonal")
6
7
8
子模式可以使用as
捕獲
1case (Point(x1, y1), Point(x2, y2) as p2): ...
2
3
9
模式可以使用命名的常量,且必須使用.
以防止被解釋爲捕獲變量
1from enum import Enum
2class Color(Enum):
3 RED = 0
4 GREEN = 1
5 BLUE = 2
6
7 match color:
8 case Color.RED:
9 print("I see red!")
10 case Color.GREEN:
11 print("Grass is green")
12 case Color.BLUE:
13 print("I'm feeling the blues :(")
14
10
字面量會被特殊對待,例如None, False, True
,是使用is
完成匹配的例如:
1match b:
2 case True:
3 print("Yes!")
4
5
就完全等價於這樣
1 if b is True:
2 print("Yes!")
3
4
多謝
關於 match-case 的用法可能已過時或理解不準確,如有錯漏地方歡迎指正,共同學習,權威及最新信息可關注 Guido 老爺子的官方 repo[1]
參考資料
[1]
Guido 老爺子的官方 repo: : https://github.com/gvanrossum/patma
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/_o6-B7DxTlTikQvGK-pNwg