여기서는 match-case를 단순 switch보다 구조를 보면서 분기하고, 그 안의 값을 바로 꺼내는 문법으로 먼저 봅니다.
값 비교만 할 것인지, tuple/dict/class 구조를 분해하며 분기할 것인지에 따라 if / elif와 match-case가 갈립니다.
숏컷 코드
def describe(command):
match command:
case ("move", x, y):
return f"move to {x}, {y}"
case {"type": "quit"}:
return "stop"
case _:
return "unknown"문법
기본형은 리터럴 패턴, sequence 패턴, mapping 패턴, OR 패턴, guard, class pattern까지 같이 보면 됩니다.
match value:
case pattern:
...
case other_pattern if condition:
...
case _:
...
match command:
case ("move", x, y):
...
case {"type": "quit"}:
...
case ClassName(attr=value):
...match-case는 "분기"와 "언패킹"을 같이 처리하는 문법입니다.
어떤 구조가 들어왔는지와, 그 안의 값을 어떻게 꺼낼지를 한 자리에서 표현할 수 있습니다.
구조 분기
tuple이나 list의 모양으로 분기하면 match-case가 잘 맞는다
명령 튜플, 토큰 시퀀스, 간단한 파싱 결과처럼 구조가 있는 값을 다룰 때 특히 읽기 좋아집니다.
match command:
case ("move", x, y):
...
case ("say", message):
...인덱스를 직접 꺼내고 길이를 확인하는 코드보다 의도가 훨씬 빠르게 보입니다.
바인딩과 조건
패턴 안에서 값을 바로 바인딩하고, guard로 세부 조건을 붙인다
성공한 패턴은 내부 값을 변수에 바로 넣어 줍니다.
point = (10, 20)
match point:
case (x, y):
print(x, y)구조가 맞는지 먼저 걸러내고, 그 다음 추가 조건을 붙이면 읽기 좋은 분기가 됩니다.
match event:
case {"type": "message", "text": text} if text.strip():
print(text)
case _:
print("ignore")패턴은 큰 모양, guard는 세부 조건이라는 역할 분리가 핵심입니다.
패턴 종류
OR 패턴과 class pattern으로 분기를 더 압축할 수 있다
여러 값을 같은 분기로 묶고 싶으면 |를 쓰고, 객체 속성으로 분기하고 싶으면 class pattern을 씁니다.
match status_code:
case 400 | 401 | 403:
print("client error")
case 500 | 503:
print("server error")from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
match point:
case Point(x=0, y=0):
print("origin")즉 match-case는 단순 분기뿐 아니라 구조적 규칙을 코드에 직접 적는 도구입니다.
선택 기준
단순 값 몇 개를 비교하면 if / elif가 더 가볍다
단순 상수 비교 몇 개만 하는 경우에는 match-case가 오히려 더 무거워 보일 수 있습니다.
핵심은 "최신 문법이라서"가 아니라, 구조를 드러낼 이점이 있을 때 쓰는 것입니다.
if status == "ready":
print("go")
elif status == "stop":
print("halt")
match command:
case ("move", x, y) | ("teleport", x, y):
print(x, y)즉 단순 값 몇 개를 비교할 때는 if / elif, 구조를 꺼내며 분기할 때는 match-case가 더 자연스럽습니다.
주의할 점
패턴 안의 이름은 기존 변수와의 비교가 아니라 새 변수 바인딩으로 해석될 수 있습니다. 상수 비교라면 리터럴이나 enum, 점 표기 이름을 명시하는 편이 안전합니다.
# ❌ SUCCESS는 비교처럼 보이지만 캡처 패턴이 될 수 있음
match status:
case SUCCESS:
print("ok")
# ✅ 리터럴이나 enum 값을 명시
match status:
case "success":
print("ok")
# ❌ 단순 값 비교만 하는데 match를 과하게 쓰면 읽기 무거워질 수 있다
match status:
case "ready":
run()
case "stop":
halt()
# ✅ 단순 상수 분기만 있으면 if/elif가 더 직접적일 수 있다
if status == "ready":
run()
elif status == "stop":
halt()참고 링크
2 sources