Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python 함수 매개변수에서 튜플을 직접 정의할 수 없는 이유

Python 3.0부터 함수 매개변수에서 튜플 언패킹이 금지된 배경

Python 3.0부터는 PEP 3113에 따라 함수 정의 시 매개변수 자리에 튜플 언패킹(unpacked tuple) 형태를 더 이상 사용할 수 없습니다. 즉, 다음과 같이 함수를 정의하려고 하면 오류가 발생합니다.

def fn(a,(b,c)):
    pass

이 코드를 실행하면 Python 인터프리터가 튜플의 첫 번째 괄호 위치에서 SyntaxError를 출력합니다.

PEP 3113은 이러한 '자동 언패킹 매개변수' 기능이 실무에서 거의 사용되지 않았고, 오히려 함수 시그니처 분석과 타입 검사 도구 구현을 복잡하게 만든다는 이유로 해당 기능을 제거했습니다. 그 결과 함수 매개변수는 단일 이름만 가질 수 있으며, 시퀀스 데이터를 받으려면 하나의 객체로 전달한 뒤 함수 내부에서 처리하는 것이 표준 방식이 되었습니다.

함수 내부에서 튜플을 언패킹하는 올바른 방법

대신 튜플 객체 자체를 매개변수로 전달하고, 함수 내부에서 언패킹하면 됩니다. 아래 코드에서는 두 점의 x, y 좌표를 담은 두 개의 튜플 객체를 매개변수로 받아 두 점 사이의 거리(유클리드 거리)를 계산합니다. 계산에 앞서 각 튜플을 x 좌표와 y 좌표로 언패킹합니다.

def hypot(p1, p2):
    x1, y1 = p1
    x2, y2 = p2
    import math
    hyp = math.sqrt((x1 - x2)**2 + (y1 - y2)**2)
    return hyp

x = (10, 10)
y = (20, 20)
print("hyp=", hypot(x, y))

실행 결과:

hyp= 14.142135623730951

추가로 알아두면 좋은 대안들

  • *args 활용: 가변 개수의 값을 받아야 한다면 *args로 여러 인수를 받은 뒤 함수 내부에서 필요한 만큼 언패킹할 수 있습니다.
  • typing.Tuple 타입 힌트: p1: tuple[int, int]처럼 타입 힌트를 붙이면 튜플의 구조와 요소 타입을 명확히 문서화할 수 있어 가독성과 유지보수성이 향상됩니다.
  • NamedTuple 또는 dataclass: 좌표처럼 의미 있는 필드를 가진 데이터라면 typing.NamedTuple이나 dataclass를 사용하면 p1.x, p1.y 형태로 속성에 접근할 수 있어 코드가 더 명확해집니다.

정리하면, Python 3.0 이후에는 함수 매개변수에서 튜플을 직접 정의하는 것이 문법적으로 허용되지 않으며, 튜플 객체를 인수로 전달하고 함수 본문 안에서 언패킹하는 방식으로 동일한 기능을 깔끔하게 구현할 수 있습니다.