패턴 매칭 메커니즘은 파이썬 3.10에서 Structural Pattern Matching이라는 이름으로 도입되어 match-case 구문을 통해 구현되었습니다. 이 도구는 복잡한 데이터 구조를 우아하고 간결하게 분석하여 템플릿과 일치시킬 수 있습니다.
많은 함수형 언어들(예: Haskell, Scala)에서 패턴 매칭은 데이터 구조에 따라 로직을 분기하는 유용한 방법으로 오랫동안 간주되어 왔습니다. 파이썬은 오랫동안 이러한 메커니즘이 없어 if-elif-else 체인이나 언팩킹으로 해결해왔습니다.
복잡한 중첩 데이터 구조(사전, 리스트, 객체)는 일반적으로 유형, 값 및 구조에 대한 다수의 검사를 요구하여 많은 조건을 가진 복잡한 코드를 초래합니다.
match-case는 조건의 중복 없이 유형과 구조를 고려하여 데이터 처리의 다양한 시나리오를 선언적이고 가독성 있게 설명할 수 있는 방법을 제공합니다.
def process(event): match event: case {"type": "click", "x": x, "y": y}: return f"Click at ({x}, {y})" case [command, *args]: return f"Command: {command}, args: {args}" case _: return "Unknown event" print(process({"type": "click", "x": 2, "y": 5})) # Click at (2, 5) print(process(["RUN", 1, 2, 3])) # Command: RUN, args: [1, 2, 3]
match-case는 값에 대해서만 일치합니까? 아니요. 일치는 구조, 유형, 컬렉션의 언팩킹 및 심지어 객체의 속성(특별 메서드 __match_args__가 명시된 경우)에 따라 발생할 수 있습니다.
match의 case 순서에 영향을 미칩니까? 예. 분석은 위에서 아래로 진행되며, 첫 번째 일치하는 템플릿이 실행됩니다. 이후의 case는 검사되지 않습니다.
사용자 정의 클래스를 일치시킬 수 있나요? 예, 클래스가 match_args 및/또는 getitem 메서드를 구현하면 패턴 매칭이 필드 값을 추출할 수 있습니다.
class Point: __match_args__ = ("x", "y") def __init__(self, x, y): self.x = x self.y = y def where(obj): match obj: case Point(x, y): return f"Point at {x}, {y}" case _: return "Unknown" print(where(Point(1, 2))) # Point at 1, 2
장점:
부정적인 사례: 개발자들이 간단한 불리언 분기에도 match-case를 사용하여 코드가 복잡해졌습니다. 장점: 새로운 기능을 배웠습니다. 단점: 가독성이 떨어지고 오류가 증가했습니다.
긍정적인 사례: 이벤트와 중첩 구조가 많은 애플리케이션(예: 그래프 파서)에서 match-case는 복잡한 if-elif를 피하고 파싱을 중앙 집권화하는 데 도움을 주었습니다. 장점: 가독성이 향상되고 버그 수가 줄어들었습니다. 단점: 새로운 구문을 작업하는 데 팀 교육이 필요했습니다.