PEP 3117 – 후위 타입 선언
- Author:
- Georg Brandl <georg at python.org>
- Status:
- Rejected
- Type:
- Standards Track
- Created:
- 01-Apr-2007
- Python-Version:
- 3.0
- Post-History:
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
이 PEP는 Python에 후위 타입 선언 구문을 추가할 것을 제안합니다. 또한 타입과 선언자 사이에 새로운 매핑을 만드는 데 사용되는 새로운 typedef 문을 지정합니다.
이를 수용하면 Python 사용자 경험이 크게 향상될 뿐만 아니라, 다른 프로그래밍 언어 사용자들이 Python으로 전환하는 것을 방해하는 단점 중 하나도 제거할 수 있습니다.
근거
Python은 오랫동안 명시적 타입 선언의 부재로 어려움을 겪어 왔습니다. 언어가 그 젠에서 벗어나는 몇 안 되는 측면 중 하나인 이 단점은 Python 이단자들과 PSU 구성원들 사이에서 많은 논의를 촉발했으며([EX1], [EX2] 또는 [EX3] 참조), Python이 대규모 기업에서 성공하는 것도 어렵게 만들었습니다.
그러나 이 고통을 끝내고자 한다면, 적절한 Python다운 구문을 찾아야 합니다. 타입 선언을 지원하는 거의 모든 언어에서 타입 선언은 이러한 특성이 부족합니다. 즉, 장황하고 단일 타입에 여러 단어가 필요한 경우가 많거나, 이해하기 어렵습니다(예를 들어 어떤 언어는 타입 선언에 전혀 관련 없는 [1] 형용사인 dim을 사용합니다).
따라서 이 PEP는 타입 선언으로의 전환을 또 하나의 대담한 변화와 결합합니다. 즉, Python이 미래를 대비할 뿐만 아니라 미래를 적극적으로 받아들이는 언어임을 다시 한번 입증할 소스 코드의 필수 구성 요소로서 유니코드 문자를 도입합니다.
유니코드를 사용하면 훨씬 적은 문자로 훨씬 더 많은 것을 표현할 수 있으며, 이는 Zen의 (“가독성이 중요합니다.”) 원칙에도 부합합니다. 또한 별도의 타입 선언 문이 필요하지 않게 하고, 이미 연산자에 유니코드를 사용하는 Perl 6에 Python이 뒤지지 않게 한다는 점도 중요합니다. [2]
명세
타입 선언 모드가 작동 중일 때는 문법이 변경되어 각 NAME이 이름과 타입 선언자라는 두 부분으로 구성되어야 하며, 타입 선언자는 정확히 하나의 유니코드 문자입니다.
선언자는 이름의 타입을 고유하게 지정하며, 표현식의 왼쪽에 나타나는 경우 해당 타입이 강제됩니다. 반환된 타입이 선언된 타입과 일치하지 않으면 InquisitionError예외가 발생합니다. [3]
또한 함수 호출 결과의 타입도 지정해야 합니다. 호출 결과가 선언된 타입이 아니면 InquisitionError예외가 발생합니다. 주의하십시오. 결과에 대한 선언자를 함수 객체에 대한 선언자와 혼동해서는 안 됩니다(아래 예제를 참조하십시오).
읽기만 하고 대입하지 않는 이름 뒤의 타입 선언자는 엄밀히 말해 필요하지 않지만, 그래도 강제됩니다(Python 젠 참조: “명시적인 것이 암시적인 것보다 낫습니다.”).
타입과 선언자 사이의 매핑은 정적이지 않습니다. 프로그래머가 이를 완전히 사용자 지정할 수 있지만, 편의를 위해 일부 내장 타입에 대한 미리 정의된 매핑이 제공됩니다.
| 타입 | 선언자 |
|---|---|
object |
� (대체 문자) |
int |
ℕ (이중선 대문자 N) |
float |
℮ (추정 기호) |
bool |
✓ (체크 표시) |
complex |
ℂ (이중선 대문자 C) |
str |
✎ (오른쪽 아래 연필) |
unicode |
✒ (검은 펜촉) |
tuple |
⒯ (괄호 라틴 소문자 T) |
list |
♨ (온천) |
dict |
⧟ (양끝 멀티맵) |
set |
∅ (공집합) (참고: 전체 집합에도 사용됩니다) |
frozenset |
☃ (눈사람) |
datetime |
⌚ (시계) |
function |
ƛ (획이 있는 라틴 소문자 람다) |
generator |
⚛ (원자 기호) |
Exception |
⌁ (전기 화살표) |
None 타입의 선언자는 폭이 0인 공백입니다.
이러한 문자는 모든 프로그래머가 분명하게 이해하고 기억하며 입력하기 쉬워야 합니다.
유니코드 대체 단위
현대의 세계화된 세상에서도 소스 코드에서 유니코드를 사용할 수 없거나 사용하기를 원하지 않는 구식 반항자들이 여전히 존재하고, Python은 관대한 언어이므로 그러한 사람들을 위한 대체 수단이 제공됩니다.
단일 유니코드 문자 대신 name${UNICODE NAME OF THE DECLARATOR}$를 입력할 수 있습니다. 예를 들어, 다음 두 함수 정의는 서로 동등합니다.:
def fooƛ(xℂ):
return None
그리고
def foo${LATIN SMALL LETTER LAMBDA WITH STROKE}$(x${DOUBLE-STRUCK CAPITAL C}$):
return None${ZERO WIDTH NO-BREAK SPACE}$
이는 여전히 읽기 쉬우며 ASCII를 신봉하는 사람들도 타입 어노테이션이 적용된 Python의 모든 기능을 사용할 수 있게 합니다.
typedef 문
타입과 선언자 간의 매핑은 이 새로운 문으로 확장할 수 있습니다.
구문은 다음과 같습니다.:
typedef_stmt ::= "typedef" expr DECLARATOR
여기서 expr은 타입 객체로 해석됩니다. 편의를 위해 새로운 클래스에 대해서는 typedef 문을 class 문과 다음과 같이 함께 사용할 수도 있습니다.:
typedef class Foo☺(object�):
pass
예제
이것은 표준 os.path.normpath 함수를 타입 선언 구문으로 변환한 것입니다.:
def normpathƛ(path✎)✎:
"""Normalize path, eliminating double slashes, etc."""
if path✎ == '':
return '.'
initial_slashes✓ = path✎.startswithƛ('/')✓
# POSIX allows one or two initial slashes, but treats three or more
# as single slash.
if (initial_slashes✓ and
path✎.startswithƛ('//')✓ and not path✎.startswithƛ('///')✓)✓:
initial_slashesℕ = 2
comps♨ = path✎.splitƛ('/')♨
new_comps♨ = []♨
for comp✎ in comps♨:
if comp✎ in ('', '.')⒯:
continue
if (comp✎ != '..' or (not initial_slashesℕ and not new_comps♨)✓ or
(new_comps♨ and new_comps♨[-1]✎ == '..')✓)✓:
new_comps♨.appendƛ(comp✎)
elif new_comps♨:
new_comps♨.popƛ()✎
comps♨ = new_comps♨
path✎ = '/'.join(comps♨)✎
if initial_slashesℕ:
path✎ = '/'*initial_slashesℕ + path✎
return path✎ or '.'
명확히 알 수 있듯이, 타입 선언은 표현력을 높이는 동시에 코드를 훨씬 더 전문적으로 보이게 합니다.
호환성 문제
타입 선언 모드를 활성화하려면 다음을 작성해야 합니다.:
from __future__ import type_declarations
이렇게 하면 소스의 유니코드 구문 분석이 활성화되고 [4], typedef가 키워드가 되며 모든 할당과 함수 호출에 올바른 타입이 적용됩니다.
거부
신중한 검토와 깊은 고민, 이를 악물고 괴로워하는 과정과 옷을 찢는 심사숙고 끝에 이 PEP를 거부하기로 결정했습니다.
참고 자료
감사의 말
내장 타입에 가장 적합하고 기억하기 쉬운 선언자를 찾는 데 도움을 주신 Armin Ronacher, Alexander Schremmer 및 Marek Kubica에게 진심으로 감사드립니다.
또한 유니코드 표준에 이처럼 유용한 문자들을 모두 포함해 주신 유니코드 컨소시엄에도 감사드립니다.
Copyright
This document has been placed in the public domain.