PEP 224 – 속성 독스트링
- Author:
- Marc-André Lemburg <mal at lemburg.com>
- Status:
- Rejected
- Type:
- Standards Track
- Created:
- 23-Aug-2000
- Python-Version:
- 2.1
- Post-History:
Table of Contents
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
소개
이 PEP는 Python 2.0을 위한 “속성 독스트링” 제안을 설명합니다. 이 PEP는 이 기능의 상태와 소유권을 추적합니다. 이 PEP에는 기능에 대한 설명과 기능 지원에 필요한 변경 사항의 개요가 담겨 있습니다. 이 파일의 CVS 리비전 이력에 확정적인 역사적 기록이 담겨 있습니다.
근거
이 PEP는 현재 Python이 Python 코드에 포함된 독스트링을 처리하는 방식에 작은 추가 사항을 제안합니다.
현재 Python은 클래스 정의나 함수 정의 바로 뒤에 오는 독스트링, 또는 모듈의 첫 번째 문자열 리터럴로 나타나는 독스트링만 처리합니다. 이 문자열 리터럴은 해당 객체의 __doc__ 속성에 추가되며, 이후에는 인트로스펙션 도구에서 사용할 수 있습니다. 이러한 도구는 도움말, 디버깅, 문서화 목적으로 그 안에 담긴 정보를 추출할 수 있습니다.
앞서 언급한 위치 이외의 곳에 나타나는 독스트링은 그냥 무시되며 어떤 코드도 생성하지 않습니다.
다음은 예시입니다:
class C:
"class C doc-string"
a = 1
"attribute C.a doc-string (1)"
b = 2
"attribute C.b doc-string (2)"
독스트링 (1)과 (2)는 현재 Python 바이트코드 컴파일러가 무시하지만, 그 앞에 오는 이름 있는 대입을 문서화하는 데 분명히 유용하게 쓰일 수 있습니다.
이 PEP는 이러한 경우도 활용하자고 제안하며, 그 내용을 새로 생성된 속성 이름으로 해당 문자열이 나타나는 객체에 추가하는 의미를 제안합니다.
위 예제에도 영감을 준 이 접근 방식의 원래 아이디어는 클래스 속성의 인라인 문서화를 가능하게 하는 것이었습니다. 현재 클래스 속성은 클래스의 독스트링이나 인트로스펙션으로 접근할 수 없는 주석으로만 문서화할 수 있습니다.
구현
바이트코드 컴파일러는 독스트링을 표현식으로 처리합니다. 현재 구현은 위에서 언급한 몇몇 위치만 특별히 처리하여 이 표현식을 활용하고, 그 밖의 경우에는 문자열을 완전히 무시합니다.
이름이 있는 대입(예를 들어 클래스 속성을 정의하는 자연스러운 방법)을 문서화하는 데 이러한 독스트링을 사용할 수 있게 하려면, 컴파일러는 마지막으로 대입된 이름을 추적해야 합니다. 그런 다음 이 이름을 사용하여 독스트링의 내용을 포함하는 객체의 속성에 대입해야 합니다. 이는 독스트링을 상수로 저장한 뒤 객체 생성 시점에 객체의 네임스페이스에 추가하는 방식으로 이루어집니다.
상속이나 Python 특수 속성(앞뒤에 이중 밑줄이 붙은 속성) 숨김과 같은 기능을 유지하려면 특별한 이름 맹글링을 적용해야 합니다. 이 맹글링은 독스트링이 해당 이름 대입에 속한다는 것을 고유하게 식별하며, 나중에 네임스페이스를 검사하여 독스트링을 찾을 수 있게 합니다.
다음 이름 맹글링 방식은 위의 요구 사항을 모두 충족합니다:
__doc_<attributename>__
마지막으로 대입된 이름을 추적하기 위해 바이트코드 컴파일러는 이 이름을 컴파일 구조체의 변수에 저장합니다. 이 변수의 기본값은 NULL입니다. 컴파일러는 독스트링을 만나면 이 변수를 확인하고, 그 이름을 바탕으로 위의 이름 맹글링을 수행하여 맹글링된 이름에 독스트링을 암묵적으로 대입하는 코드를 생성합니다. 그런 다음 중복 대입을 피하기 위해 변수를 NULL로 재설정합니다.
변수가 이름을 가리키지 않으면(즉, NULL이면) 아무런 대입도 이루어지지 않습니다. 이러한 독스트링은 이전과 마찬가지로 계속 무시됩니다. 기존의 모든 독스트링이 이 경우에 해당하므로 중복 대입은 일어나지 않습니다.
위 예제에서는 이에 따라 다음과 같은 새 클래스 속성이 생성됩니다:
C.__doc_a__ == "attribute C.a doc-string (1)"
C.__doc_b__ == "attribute C.b doc-string (2)"
위 내용을 구현한 현재 CVS 버전 Python 2.0용 패치는 SourceForge [1]에서 구할 수 있습니다.
구현상의 주의 사항
구현은 비표현식(예: 함수 정의)을 처리할 때 컴파일 구조체 변수를 초기화하지 않습니다. 따라서 마지막으로 대입된 이름은 다음 대입이 나오거나 다음 독스트링이 나타날 때까지 활성 상태로 남아 있습니다.
이 때문에 독스트링과 대입 사이에 다른 표현식이 끼어드는 경우가 생길 수 있습니다:
class C:
"C doc string"
b = 2
def x(self):
"C.x doc string"
y = 3
return 1
"b's doc string"
현재 메서드 “x”의 정의는 사용된 대입 이름 변수를 초기화하지 않습니다. 그래서 컴파일러가 독스트링 “b’s doc string”에 도달했을 때 이 변수가 여전히 유효하고, 컴파일러는 이 문자열을 __doc_b__에 대입합니다.
이 문제는 컴파일러에서 모든 비표현식 노드에 대해 이름 변수를 초기화하는 방법으로 해결할 수 있습니다.
발생할 수 있는 문제
가능성은 매우 낮지만, 속성 독스트링이 실수로 속성의 값에 연결될 수 있습니다:
class C:
x = "text" \
"x's docstring"
끝에 붙은 슬래시 때문에 Python 컴파일러가 속성 값과 독스트링을 연결하게 됩니다.
하지만 최신 문법 강조 편집기라면 이러한 실수를 쉽게 드러내 줍니다. 또한 속성 정의와 독스트링 사이에 빈 줄을 넣기만 하면 이러한 연결 가능성을 완전히 피할 수 있으므로 이 문제는 무시할 만합니다.
또 다른 문제는 삼중 따옴표 문자열로 코드 일부를 주석 처리하는 경우입니다.
주석 문자열이 시작되기 바로 전에 대입이 있으면, 컴파일러는 그 주석을 독스트링 속성으로 취급하고 위의 로직을 적용합니다.
문서화되지 않았을 속성에 독스트링이 생성된다는 점 외에는 기존 코드가 깨지는 일은 없습니다.
BDFL의 의견
이 PEP에 대한 Guido의 초기 의견은 다음과 같습니다:
저는 속성 독스트링이라는 아이디어가 “어느 정도” 마음에 듭니다(제게 아주 중요한 일은 아니라는 뜻입니다). 하지만 현재 제안에는 마음에 들지 않는 점이 두 가지 있습니다:
- 제안하신 문법은 너무 모호합니다. 말씀하신 대로, 단독으로 쓰인 문자열 리터럴은 다른 용도로도 사용되며 갑자기 속성 독스트링이 되어 버릴 수 있습니다.
- 접근 방식(
__doc_<attrname>__)도 마음에 들지 않습니다.
저자의 답변:
> 1. The syntax you propose is too ambiguous: as you say, stand-alone > string literal are used for other purposes and could suddenly > become attribute docstrings.이는 컴파일러에 몇 가지 추가 검사를 도입하여 컴파일러 구조체의 “doc 속성(doc attribute)” 플래그를 재설정하도록 하면 해결할 수 있습니다.
> 2. I don't like the access method either (``__doc_<attrname>__``).다른 이름이라도 상관없습니다. 다음 기준만 충족하면 됩니다:
- 밑줄 두 개로 시작해야 합니다(
__doc__과 맞추기 위해)- 어떤 형태의 검사로든 추출할 수 있어야 합니다(예: 고정된 이름 부분을 포함하는 명명 규칙 사용)
- 클래스 상속과 호환되어야 합니다(즉, 속성으로 저장되어야 합니다)
이후 Guido는 2001년 3월에 (python-dev에서) 이 PEP에 대한 결정을 발표했습니다. 다음은 귀도가 이 PEP의 저자에게 보낸 개인 메일에서 밝힌 거절 이유입니다:
…유용할 수도 있겠지만, 제안된 문법이 정말 싫습니다.
a = 1 "foo bar" b = 1“foo bar”가 a의 독스트링인지 b의 독스트링인지 알 방법이 전혀 없습니다.
…
다음 관례를 사용할 수 있습니다:
a = 1 __doc_a__ = "doc string for a"이렇게 하면 런타임에 사용할 수 있습니다.
> Are you completely opposed to adding attribute documentation > to Python or is it just the way the implementation works ? I > find the syntax proposed in the PEP very intuitive and many > other users on c.l.p and in private emails have supported it > at the time I wrote the PEP.문제는 구현이 아니라 문법입니다. 변수와 독스트링 문자열 사이의 연결 관계를 충분히 명확하게 전달하지 못합니다.
Copyright
This document has been placed in the Public Domain.