PEP 257 – 독스트링 규약
- Author:
- David Goodger <goodger at python.org>, Guido van Rossum <guido at python.org>
- Discussions-To:
- Doc-SIG list
- Status:
- Active
- Type:
- Informational
- Created:
- 29-May-2001
- Post-History:
- 13-Jun-2001
Table of Contents
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
이 PEP는 Python 독스트링과 관련된 의미와 관례를 문서화합니다.
근거
이 PEP의 목적은 독스트링의 상위 수준 구조, 즉 독스트링에 무엇을 담아야 하고 그것을 어떻게 표현해야 하는지를 표준화하는 것입니다(독스트링 안의 마크업 문법은 다루지 않습니다). 이 PEP에 담긴 것은 규약이지, 법이나 문법이 아닙니다.
“보편적인 규약은 유지 보수성, 명확성, 일관성은 물론 좋은 프로그래밍 습관의 토대까지 모두 제공합니다. 다만 여러분의 의사에 반해 그것을 따르라고 강요하지는 않습니다. 그것이 바로 Python입니다!”—Tim Peters, comp.lang.python에서, 2001-06-16
이 규약을 어긴다고 해도, 기껏해야 따가운 눈총을 받는 정도입니다. 하지만 일부 소프트웨어(예를 들어 Docutils 독스트링 처리 시스템 PEP 256, PEP 258)는 이 규약을 인식하므로, 규약을 따르면 가장 좋은 결과를 얻을 수 있습니다.
명세
독스트링이란 무엇입니까?
독스트링은 모듈, 함수, 클래스, 메서드 정의에서 첫 번째 문장으로 나타나는 문자열 리터럴입니다. 이러한 독스트링은 해당 객체의 __doc__ 특수 속성이 됩니다.
일반적으로 모든 모듈에는 독스트링이 있어야 하며, 모듈이 내보내는 모든 함수와 클래스에도 독스트링이 있어야 합니다. 공개 메서드(__init__ 생성자 포함)에도 독스트링이 있어야 합니다. 패키지는 패키지 디렉터리에 있는 __init__.py 파일의 모듈 독스트링으로 문서화할 수 있습니다.
Python 코드의 다른 곳에 나타나는 문자열 리터럴도 문서 역할을 할 수 있습니다. 이러한 문자열 리터럴은 Python 바이트코드 컴파일러가 인식하지 않으며 런타임 객체 속성으로 접근할 수도 없지만(즉, __doc__에 할당되지 않지만), 소프트웨어 도구가 두 종류의 추가 독스트링을 추출할 수 있습니다:
- 모듈, 클래스,
__init__메서드의 최상위 수준에서 단순 할당 바로 다음에 나타나는 문자열 리터럴을 “속성 독스트링”이라고 합니다. - 다른 독스트링 바로 다음에 나타나는 문자열 리터럴을 “부가 독스트링”이라고 합니다.
속성 독스트링과 추가 독스트링에 대한 자세한 설명은 PEP 258 “Docutils Design Specification”(Docutils 설계 명세)을 참고하십시오.
일관성을 위해, 독스트링은 항상 """triple double quotes"""로 감싸십시오. 독스트링에 백슬래시를 사용한다면 r"""raw triple double quotes"""를 사용하십시오.
독스트링에는 한 줄 독스트링과 여러 줄 독스트링이라는 두 가지 형태가 있습니다.
한 줄 독스트링
한 줄 독스트링은 정말로 명백한 경우를 위한 것입니다. 이러한 독스트링은 실제로 한 줄에 들어가야 합니다. 예를 들면 다음과 같습니다:
def kos_root():
"""Return the pathname of the KOS root directory."""
global _kos_root
if _kos_root: return _kos_root
...
참고 사항:
- 문자열이 한 줄에 들어가더라도 삼중 따옴표를 사용합니다. 이렇게 하면 나중에 내용을 쉽게 확장할 수 있습니다.
- 닫는 따옴표는 여는 따옴표와 같은 줄에 둡니다. 한 줄짜리 독스트링에서는 이렇게 하는 편이 더 보기 좋습니다.
- 독스트링 앞이나 뒤에 빈 줄을 두지 않습니다.
- 독스트링은 마침표로 끝나는 구절입니다. 독스트링은 함수나 메서드의 효과를 설명이 아닌 명령(“Do this”, “Return that”)으로 규정합니다. 예를 들어 “Returns the pathname …”과 같이 작성하지 마십시오.
- 한 줄 독스트링은 함수나 메서드의 매개변수를 되풀이하는 “시그니처”가 되어서는 안 됩니다(매개변수는 인트로스펙션으로 얻을 수 있습니다). 다음과 같이 작성하지 마십시오:
def function(a, b): """function(a, b) -> list"""
이러한 유형의 독스트링은 인트로스펙션이 불가능한 C 함수(내장 함수 등)에만 적합합니다. 그러나 반환값의 성질은 인트로스펙션으로 알아낼 수 없으므로 이를 언급해야 합니다. 이러한 독스트링의 바람직한 형태는 대략 다음과 같습니다:
def function(a, b): """Do X and return a list."""
(물론 “Do X”는 유용한 설명으로 바꾸어야 합니다!)
여러 줄 독스트링
여러 줄 독스트링은 한 줄짜리 독스트링과 마찬가지로 요약 줄로 시작하고, 그 뒤에 빈 줄이 오며, 이어서 더 자세한 설명이 옵니다. 요약 줄은 자동 색인 도구에서 사용될 수 있으므로, 요약 줄이 한 줄에 들어가고 독스트링의 나머지 부분과 빈 줄로 구분되는 것이 중요합니다. 요약 줄은 여는 따옴표와 같은 줄에 두어도 되고 다음 줄에 두어도 됩니다. 독스트링 전체는 첫 줄의 따옴표와 같은 수준으로 들여씁니다(아래 예제를 참고하십시오).
클래스를 문서화하는 모든 독스트링(한 줄짜리든 여러 줄이든) 뒤에는 빈 줄을 넣으십시오. 일반적으로 클래스의 메서드들은 서로 빈 줄 하나로 구분되므로, 독스트링도 첫 번째 메서드와 빈 줄로 떨어뜨려 두어야 합니다.
스크립트(독립 실행형 프로그램)의 독스트링은 스크립트가 잘못된 인자로 호출되거나 인자가 누락된 채 호출될 때(또는 “도움말”을 위한 “-h” 옵션으로 호출될 때) 출력되는 “사용법” 메시지로 사용할 수 있어야 합니다. 이러한 독스트링에는 스크립트의 기능(함수)과 명령줄 문법, 환경 변수, 파일을 문서화해야 합니다. 사용법 메시지는 꽤 자세해도 되며(여러 화면 분량), 새로운 사용자가 명령을 올바르게 사용하기에 충분해야 할 뿐 아니라 숙련된 사용자에게는 모든 옵션과 인자에 대한 완전한 빠른 참조가 되어야 합니다.
모듈의 독스트링에는 일반적으로 모듈이 내보내는 클래스, 예외, 함수(및 기타 객체)를 각각의 한 줄 요약과 함께 나열해야 합니다. (이러한 요약은 일반적으로 해당 객체의 독스트링에 있는 요약 줄보다 덜 자세합니다.) 패키지의 독스트링(즉, 패키지의 __init__.py 모듈의 독스트링)에도 패키지가 내보내는 모듈과 하위 패키지를 나열해야 합니다.
함수나 메서드의 독스트링에는 그 동작을 요약하고, 인자, 반환값, 부작용, 발생하는 예외, 호출할 수 있는 시점에 대한 제약 사항을 (해당하는 경우 모두) 문서화해야 합니다. 선택적 인자는 표시해야 합니다. 키워드 인자가 인터페이스의 일부인지 여부를 문서화해야 합니다.
클래스의 독스트링에는 그 동작을 요약하고 공개 메서드와 인스턴스 변수를 나열해야 합니다. 클래스가 서브클래싱될 것을 의도하고 서브클래스를 위한 추가 인터페이스가 있다면, 이 인터페이스는 (독스트링에) 따로 나열해야 합니다. 클래스 생성자는 해당 클래스의 __init__ 메서드의 독스트링에 문서화해야 합니다. 개별 메서드는 각자의 독스트링으로 문서화해야 합니다.
클래스가 다른 클래스의 서브클래스이고 동작 대부분을 그 클래스로부터 상속받는다면, 독스트링에 이 사실을 언급하고 차이점을 요약해야 합니다. 서브클래스 메서드가 슈퍼클래스 메서드를 대체하며 슈퍼클래스 메서드를 호출하지 않음을 나타낼 때는 “override”라는 동사를 사용하고, 서브클래스 메서드가 (자신의 동작에 더하여) 슈퍼클래스 메서드를 호출함을 나타낼 때는 “extend”라는 동사를 사용하십시오.
본문에서 함수나 메서드의 인자를 대문자로 언급하는 Emacs 관례를 사용하지 마십시오. Python은 대소문자를 구분하며 인자 이름을 키워드 인자로 사용할 수 있으므로, 독스트링에는 올바른 인자 이름을 기록해야 합니다. 각 인자를 별도의 줄에 나열하는 것이 가장 좋습니다. 예를 들면 다음과 같습니다:
def complex(real=0.0, imag=0.0):
"""Form a complex number.
Keyword arguments:
real -- the real part (default 0.0)
imag -- the imaginary part (default 0.0)
"""
if imag == 0.0 and real == 0.0:
return complex_zero
...
독스트링 전체가 한 줄에 들어가지 않는 경우에는 닫는 따옴표를 별도의 줄에 단독으로 두십시오. 이렇게 하면 Emacs의 fill-paragraph 명령을 독스트링에 사용할 수 있습니다.
독스트링 들여쓰기 처리
독스트링 처리 도구는 독스트링의 두 번째 줄부터 일정한 양의 들여쓰기를 제거하며, 그 양은 첫 줄 이후에 있는 비어 있지 않은 모든 줄의 최소 들여쓰기와 같습니다. 독스트링 첫 줄(즉, 첫 번째 줄바꿈까지)에 있는 들여쓰기는 의미가 없으며 제거됩니다. 독스트링에서 이후 줄들의 상대적인 들여쓰기는 유지됩니다. 독스트링의 시작과 끝에 있는 빈 줄은 제거해야 합니다.
코드는 말보다 훨씬 정확하므로, 다음은 이 알고리즘의 구현입니다:
def trim(docstring):
if not docstring:
return ''
# Convert tabs to spaces (following the normal Python rules)
# and split into a list of lines:
lines = docstring.expandtabs().splitlines()
# Determine minimum indentation (first line doesn't count):
indent = sys.maxsize
for line in lines[1:]:
stripped = line.lstrip()
if stripped:
indent = min(indent, len(line) - len(stripped))
# Remove indentation (first line is special):
trimmed = [lines[0].strip()]
if indent < sys.maxsize:
for line in lines[1:]:
trimmed.append(line[indent:].rstrip())
# Strip off trailing and leading blank lines:
while trimmed and not trimmed[-1]:
trimmed.pop()
while trimmed and not trimmed[0]:
trimmed.pop(0)
# Return a single string:
return '\n'.join(trimmed)
이 예제의 독스트링에는 줄바꿈 문자가 두 개 들어 있으므로 3줄입니다. 첫 줄과 마지막 줄은 비어 있습니다:
def foo():
"""
This is the second line of the docstring.
"""
예를 들어 설명하면 다음과 같습니다:
>>> print repr(foo.__doc__)
'\n This is the second line of the docstring.\n '
>>> foo.__doc__.splitlines()
['', ' This is the second line of the docstring.', ' ']
>>> trim(foo.__doc__)
'This is the second line of the docstring.'
다듬고 나면 이 독스트링들은 동등합니다:
def foo():
"""A multi-line
docstring.
"""
def bar():
"""
A multi-line
docstring.
"""
참고 문헌 및 각주
Copyright
This document has been placed in the public domain.
Acknowledgements
The “Specification” text comes mostly verbatim from PEP 8 by Guido van Rossum.
This document borrows ideas from the archives of the Python Doc-SIG. Thanks to all members past and present.