PEP 457 – 위치 전용 매개변수 표기법
- Author:
- Larry Hastings <larry at hastings.org>
- Discussions-To:
- Python-Dev list
- Status:
- Final
- Type:
- Informational
- Created:
- 08-Oct-2013
Table of Contents
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
개요
이 PEP는 Python의 위치 전용 매개변수를 위한 표기법을 제안합니다. 위치 전용 매개변수는 외부에서 사용할 수 있는 이름이 없는 매개변수입니다. 위치 전용 매개변수를 받는 함수를 호출하면 위치 인자는 오로지 위치만을 기준으로 이 매개변수들에 대응됩니다.
이 PEP는 위치 전용 매개변수를 사용하는 API를 기술할 때(예: Argument Clinic(인자 클리닉)이나 inspect.Signature 객체의 문자열 표현에서) 사용할 표기법을 설명하는 정보성 PEP입니다. 별도의 PEP인 PEP 570은 이 표기법을 완전한 Python 문법으로 격상할 것을 제안합니다.
근거
Python은 항상 위치 전용 매개변수를 지원해 왔습니다. 초기 버전의 Python에는 매개변수를 이름으로 지정한다는 개념이 없었으므로 당연히 모든 매개변수가 위치 전용이었습니다. 이는 Python 1.0 무렵에 바뀌었으며, 그때 모든 매개변수가 갑자기 위치-또는-키워드 매개변수가 되었습니다. 하지만 현재 버전의 Python에서도 많은 CPython “내장” 함수는 여전히 위치 전용 인자만 받습니다.
현대 Python으로 구현한 함수는 가변 *args 매개변수를 통해 임의 개수의 위치 전용 인자를 받을 수 있습니다. 하지만 특정 개수의 위치 전용 매개변수를 받도록 지정하는 Python 문법은 없습니다. 달리 말하면, 시그니처를 Python 문법으로 도저히 표현할 수 없는 내장 함수가 많습니다.
이 PEP는 그러한 시그니처를 위한 표기법을 제안하며, 이 표기법은 모든 내장 함수를 순수 Python 코드로 구현할 수 있게 해 줄 하위 호환 문법의 기초가 될 수 있습니다(해당 제안은 PEP 570을 참조하십시오).
현재 Python의 위치 전용 매개변수 의미론
위치 전용 매개변수만 받는 내장 함수의 예는 정말 많습니다. 그 결과로 나타나는 의미론은 Python 프로그래머라면 쉽게 경험할 수 있습니다. 그런 함수 하나를 골라 인자를 이름으로 지정하여 호출해 보십시오:
>>> pow(x=5, y=3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: pow() takes no keyword arguments
또한 특히 흥미로운 의미론을 가진 함수도 몇 가지 있습니다:
range(): 필수 매개변수의 왼쪽에 오는 선택적 매개변수를 받습니다. [2]dict(): 매핑/이터레이터 매개변수가 선택적이며, 의미상 반드시 위치 전용이어야 합니다. 이 매개변수에 외부에서 보이는 이름이 있다면, 그 이름은**kwarg키워드 가변 매개변수 딕셔너리로 들어가야 할 같은 이름을 가려 버릴 것입니다! [1]
물론 (*args, **kwargs)를 받아 인자를 직접 파싱하면 이 중 어느 것이든 순수 Python 코드로 흉내 낼 수 있습니다. 하지만 그렇게 하면 인자 파싱을 구현하는 수고는 차치하더라도, Python 함수의 시그니처와 실제로 받는 인자 사이에 괴리가 생깁니다.
동기
이 PEP는 Python에 위치 전용 매개변수를 구현하자고 제안하지 않습니다. 이 PEP의 목표는 단지 문법을 정의하는 것이며, 그 목적은 다음과 같습니다:
- 문서에서 함수의 인자가 어떻게 해석되는지를 명확하고 모호함 없이 일관되게 정확히 표현할 수 있습니다.
- 언젠가 커뮤니티가 언어에 위치 전용 매개변수를 추가하기로 결정할 경우에 대비하여 이 문법을 향후 사용을 위해 예약해 둡니다.
- Argument Clinic이 내장 함수의 인자를 정의할 때 입력의 일부로 이 문법의 변형을 사용할 수 있습니다.
위치 전용 매개변수 문서화의 현황
위치 전용 매개변수에 대한 문서는 불완전하고 일관성이 없습니다:
- 일부 함수는 위치 전용 인자의 선택적 그룹을 중첩된 대괄호로 감싸서 나타냅니다. [3]
- 일부 함수는 인자 개수가 서로 다른 여러 프로토타입을 제시하는 방식으로 위치 전용 인자의 선택적 그룹을 나타냅니다. [4]
- 일부 함수는 위의 두 방식을 모두 사용합니다. [2] [5]
고려해야 할 중요한 사항이 하나 더 있습니다. 현재 문서에서는 함수가 위치 전용 매개변수를 받는지 알 수 있는 방법이 없습니다. open()은 키워드 인자를 받지만 ord()는 받지 않는데, 문서만 읽어서는 이 사실을 알 방법이 없습니다.
문법과 의미
“만 피트 상공에서 내려다본 관점”에서 보고, *args와 **kwargs는 일단 무시하면, 현재 함수 정의의 문법은 다음과 같습니다:
def name(positional_or_keyword_parameters, *, keyword_only_parameters):
이 관점을 바탕으로 하면, 함수의 새 문법은 다음과 같을 것입니다:
def name(positional_only_parameters, /, positional_or_keyword_parameters,
*, keyword_only_parameters):
/ 앞의 모든 매개변수는 위치 전용입니다. 함수 시그니처에 /가 지정되지 않으면, 그 함수는 위치 전용 매개변수를 전혀 받지 않습니다.
위치 전용 매개변수는 기본값을 가질 수 있으며, 기본값이 있으면 선택적입니다. 기본값이 없는 위치 전용 매개변수는 “필수” 위치 전용 매개변수입니다.
위치 전용 매개변수의 추가적인 의미는 다음과 같습니다:
- 위치 전용 매개변수는 기술적으로는 이름을 가지지만, 이 이름은 내부에서만 쓰입니다. 위치 전용 매개변수는 외부에서 이름으로 절대 지정할 수 없습니다. (
*args및**kwargs와 마찬가지입니다.) /뒤에 인자가 있다면, 키워드 전용 매개변수로의 전환을 나타내는*뒤에 쉼표가 있는 것과 마찬가지로/뒤에 반드시 쉼표를 지정해야 합니다.- 이 문법은
*args나**kwargs에는 아무런 영향을 주지 않습니다.
추가적인 제약
Argument Clinic(인자 클리닉)은 내장 함수를 지정하는 데 이 문법의 한 형태를 사용합니다. Argument Clinic은 이론적으로는 불필요하지만 구현을 더 쉽게 만들어 주는 추가적인 제약을 둡니다. 구체적으로는 다음과 같습니다:
- 위치 전용 매개변수를 가진 함수는 현재 다른 종류의 매개변수를 가질 수 없습니다. (이 제약은 가까운 미래에 약간 완화될 가능성이 높습니다.)
- Argument Clinic(인자 클리닉)은 “선택적 그룹(optional groups)”이라는 추가 문법을 지원합니다. “선택적 그룹”은 하나의 그룹으로서 함께 지정되거나 함께 지정되지 않아야 하는 연속된 위치 전용 매개변수의 집합입니다. 예를 들어 Argument Clinic에서 매개변수 네 개를 받는 함수를 정의하고, 그 매개변수가 모두 위치 전용이며 하나의 선택적 그룹에 속한다면, 그 함수를 호출할 때는 인자를 0개 또는 4개 지정해야 합니다. 이는 Python의 레거시 라이브러리를 더 많이 다루기 위해 필요하지만, 이 PEP의 범위를 벗어나며 Python 언어에 실제로 포함하는 것은 권장하지 않습니다.
향후 구현자를 위한 참고 사항
향후 Python 버전에서 위치 전용 매개변수를 구현하기로 결정한다면, 그 의미를 보존하기 위해 몇 가지 추가 작업을 해야 합니다. 문제는 이것입니다. 함수가 호출될 때 어떤 매개변수에 값이 전달되지 않았다는 사실을 그 매개변수에 어떻게 알려야 합니까?
명백한 해결책은 매개변수가 인자에 대응되지 않았을 때 전달되는 새로운 싱글턴 상수를 Python에 추가하는 것입니다. 저는 그 값을 undefined라고 부르고, Undefined라는 특수 클래스의 싱글턴으로 만들 것을 제안합니다. 위치 전용 매개변수가 호출 시 인자를 받지 못했다면, 그 값은 undefined로 설정됩니다.
그러나 이는 또 다른 문제를 일으킵니다. “이 위치 전용 매개변수가 인자를 받지 못했다”는 경우와 “호출자가 이 매개변수에 undefined를 전달했다”는 경우를 어떻게 구별할 수 있습니까?
함수에 인자로 undefined를 전달하는 것을 금지하여, 예컨대 예외를 발생시키도록 하면 좋을 것입니다. 하지만 그렇게 하면 Python이 느려지며, 여기에는 “동의한 성인(consenting adults)” 원칙이 적용되는 것으로 보입니다. 따라서 이를 금지하기보다는 강력히 권장하지 않는 정도에 그치고, 완전히 막지는 않는 것이 좋을 것입니다.
그러나 사용자 함수가 매개변수의 기본값으로 undefined를 지정하는 것은 허용되어야(그리고 권장되어야) 합니다.
미해결 질문
Python에는 세 가지 유형의 매개변수가 있습니다:
- 위치 전용 매개변수,
- 위치-또는-키워드 매개변수, 그리고
- 키워드 전용 매개변수입니다.
Python은 함수가 2와 3을 모두 갖는 것을 허용합니다. 그리고 일부 내장 함수(예: range)는 1과 3을 모두 갖습니다. 1과 2를 모두 갖는 함수를 두는 것이 타당합니까? 아니면 위의 세 가지를 모두 갖는 함수는 어떻습니까?
감사의 말
위치 전용 매개변수와 위치-또는-키워드 매개변수 사이의 구분자로 ‘/’를 사용하는 아이디어는 2012년에 이를 제안한 Guido van Rossum의 공입니다. [6]
왼쪽 옵션 그룹에 더 높은 우선순위를 부여하는 아이디어는 Alyssa Coghlan의 공입니다. (PyCon US 2013에서 직접 나눈 대화에서 나왔습니다.)
Copyright
This document has been placed in the public domain.