學習路線:B站
普通的if判斷
def if_traffic_light(color):if color == 'red':return 'Stop'elif color == 'yellow':return 'Slow down'elif color == 'green':return 'Go'else:return 'Invalid color'print(if_traffic_light('red')) # Output: Stop
print(if_traffic_light('yellow')) # Output: Slow down
print(if_traffic_light('green')) # Output: Go
print(if_traffic_light('blue')) # Output: Invalid color
使用match-case方式,同樣達到效果:
def match_case_1(color):match color:case 'red':return 'Stop'case 'green':return 'Go'case 'yellow':return 'Caution'case _:return 'Invalid color'
print(match_case_1('red'))
print(match_case_1('green'))
print(match_case_1('yellow'))
match-case 解包
普通的if語句:
def if_point(point: tuple):if len(point) == 2:if point[0] == 0 and point[1] == 0:print("origin")else:print(f"x={point[0]}, y={point[1]}")else:print("invalid point")
使用match-case改進:
# 使用match-case 解包
def match_case_1(point: tuple):"""使用match-case解包, 解包后可以使用變量名來訪問元組中的元素,可以使用通配符_來匹配任意值"""match point:case (0, 0):print(f"Origin")case (x, y):print(f"x={x}, y={y}")case other: # 也可以用下劃線代替print(f"{other}Unknown point")match_case_1((1, 2)) # x=1, y=2
match_case_1((0, 0)) # Origin
match_case_1((1,)) # (1,)Unknown point
match_case_1((1, 2, 3)) # (1, 2, 3)Unknown point
match-case 解包升級
# 使用match-case 解包
def match_case_1(point: tuple):"""使用match-case解包, 解包后可以使用變量名來訪問元組中的元素,可以使用通配符_來匹配任意值"""match point:case (0, 0):print(f"Origin")case (x, 0):print(f"on x-axis x={x}, y=0")case (0, y):print(f"on y-axis x=0, y={y}")case (x, y):print(f"x={x}, y={y}")case other:print(f"{other}Unknown point")match_case_1((0, 1)) # on y-axis x=0, y=1
match_case_1((2,0)) # on x-axis x=2, y=0
match_case_1((1, 2, 3)) # (1, 2, 3)Unknown point
match-case 解包支持邏輯判斷
# 使用match-case 解包
def match_case_1(point: tuple):"""使用match-case解包, 解包后可以使用變量名來訪問元組中的元素,可以使用通配符_來匹配任意值"""match point:case (0, 0):print(f"Origin")case (x, 0) | (0, x): # 這里是或邏輯print(f"on axis")case (x, y):print(f"x={x}, y={y}")case other:print(f"{other}Unknown point")match_case_1((0, 1)) # on y-axis x=0, y=1
match_case_1((2,0)) # on x-axis x=2, y=0
match_case_1((1, 2, 3)) # (1, 2, 3)Unknown point
match case 不會區分序列的類型,tuple與list是一樣的
my_tuple = (1, 2)
my_list = [1, 2]
my_tuple = (1, 2)
my_list = [1, 2]match my_tuple:case 1, 2: # 可以匹配上print("Tuple matches (1, 2)")match my_list:case 1, 2: # 可以匹配上print("List matches [1, 2]")match my_tuple:case (1, 2): # 可以匹配上print("Tuple matches (1, 2)")match my_list:case [1, 2]: # 同樣可以匹配print("List matches [1, 2]")
如果需要區分類型,則可以修改:
my_tuple = (1, 2)
my_list = [1, 2]match my_list:case tuple((1, 2)): # 無法匹配print("Tuple matches (1, 2)")match my_tuple:case tuple((1, 2)): # 可以匹配print("Tuple matches (1, 2)")
進一步的,match case 也可以匹配類型,而不必關心具體內容:
my_tuple = (1, 2)
my_list = [1, 2]match my_tuple:case tuple():print("Tuple match")case list():print("List match")
match case 支持條件判斷
def match_quadrant(point):match point:case (x, y) if x > 0 and y > 0:return "First quadrant"case (x, y) if x < 0 and y > 0:return "Second quadrant"case (x, y) if x < 0 and y < 0:return "Third quadrant"case (x, y) if x > 0 and y < 0:return "Fourth quadrant"case (0, _) | (_, 0):return "On the axis"case _:return "Invalid point"point1 = (5, 3)
point2 = (-2, 7)
print(match_quadrant(point1))
print(match_quadrant(point2))
match case 字典匹配
dict_p = {'x': 1, 'y': 2}match dict_p:case {'x': 0, 'y': 0}:print('origin')case {'x': x, 'y': y}:print(f'x={x}, y={y}')
也可以部分匹配:
dict_p = {'x': 1, 'y': 2}match dict_p:case {'x': 0, 'y': 0}:print('origin')case {'x':1 }:print(f'x={x}, y={y}')
match case 匹配自定義類
class Point:def __init__(self, x, y):self.x = xself.y = yp = Point(1, 2)
match p:# 這里的case匹配的是p的類型和值,值必須是關鍵字參數# 否則報錯:TypeError: Point() accepts 0 positional sub-patterns (2 given)case Point(x=1, y=2):print("Point is (1, 2)")case Point(x=3, y=4):print("Point is (3, 4)")case _:print("Point is not (1, 2) or (3, 4)")
如果想要在case中使用位置參數,需要添加類變量__match_args__ = ("x", "y")
:
class Point:# 指定macth case中的位置參數__match_args__ = ("x", "y")def __init__(self, x, y):self.x = xself.y = yp = Point(1, 2)
match p:# 這里的case匹配的是p的類型和值,值必須是關鍵字參數case Point(x, y):print("Point is (1, 2)")case Point(x=3, y=4):print("Point is (3, 4)")case _:print("Point is not (1, 2) or (3, 4)")