Python에서 클래스 속성을 문서화하는 방법은 무엇입니까? [닫은]


115

나는 속성이 공개적으로 액세스 할 수 있도록 의도 된 경량 클래스를 작성하고 있으며 때로는 특정 인스턴스화에서만 재정의됩니다. Python 언어에는 클래스 속성 또는 모든 종류의 속성에 대한 독 스트링을 생성하기위한 규정이 없습니다. 이러한 속성을 문서화하기 위해 예상되고 지원되는 방법은 무엇입니까? 현재 나는 이런 종류의 일을하고 있습니다.

class Albatross(object):
    """A bird with a flight speed exceeding that of an unladen swallow.

    Attributes:
    """

    flight_speed = 691
    __doc__ += """
        flight_speed (691)
          The maximum speed that such a bird can attain.
    """

    nesting_grounds = "Raymond Luxury-Yacht"
    __doc__ += """
        nesting_grounds ("Raymond Luxury-Yacht")
          The locale where these birds congregate to reproduce.
    """

    def __init__(self, **keyargs):
        """Initialize the Albatross from the keyword arguments."""
        self.__dict__.update(keyargs)

이렇게하면 초기 표준 독 스트링 섹션이 포함 된 클래스의 독 스트링이 생성되고에 대한 추가 할당을 통해 각 속성에 추가 된 행이 생성됩니다 __doc__.

이 스타일은 독 스트링 스타일 가이드 라인 에서 명시 적으로 금지 된 것 같지는 않지만 옵션으로 언급되지 않았습니다. 여기서의 장점은 속성을 정의와 함께 문서화하는 방법을 제공하는 동시에 표현 가능한 클래스 독 스트링을 생성하고 독 스트링의 정보를 반복하는 주석을 작성하지 않아도된다는 것입니다. 실제로 속성을 두 번 작성해야한다는 사실에 여전히 약간 짜증이납니다. 적어도 기본값의 중복을 피하기 위해 독 스트링에있는 값의 문자열 표현을 사용하는 것을 고려하고 있습니다.

이것은 임시 커뮤니티 규약에 대한 가혹한 위반입니까? 괜찮아? 더 좋은 방법이 있습니까? 예를 들어, 속성에 대한 값과 독 스트링을 포함하는 사전을 만든 다음 클래스에 내용을 추가 __dict__하고 클래스 선언의 끝 부분에 독 스트링 을 추가 할 수 있습니다 . 이렇게하면 속성 이름과 값을 두 번 입력 할 필요가 없습니다. 편집 :이 마지막 아이디어는 실제로 가능하지 않다고 생각합니다. 적어도 데이터에서 전체 클래스를 동적으로 구축하지 않고서는 불가능하다고 생각합니다. 다른 이유가 없다면 정말 나쁜 아이디어처럼 보입니다.

저는 파이썬에 익숙하지 않고 코딩 스타일에 대한 세부 사항을 계속 작업하고 있으므로 관련없는 비평도 환영합니다.


Django 모델 속성을 문서화하는 방법을 찾고 있다면 도움이 될 것입니다. djangosnippets.org/snippets/2533
Michael Scheper

3
파이썬에서 필드와 속성을 문서화하는 방법의 중복 ? 다른 솔루션을 보유하고 있습니다.
bufh

1
나는 이것이 의견에 근거한 이유를 이해하지 못합니다. Python은 특히 PEP에서 허용되는 규칙을 문서화합니다. 적절한 형식의 문서를 추출하는 다양한 Python 소스 도구가 있습니다. 실제로 Python attribute doc stringPEP 257 에 잘 알려지지 않았으며 OP 질문에 답할 수있는 찾기 어려운 것으로 보이는 언급이 있으며 일부 소스 도구에서 지원합니다. 이것은 의견이 아닙니다. 그것은 사실이고 언어의 일부이며 OP가 원하는 것입니다.
NeilG

답변:


83

혼란을 방지하려면 : 용어 속성은의미 특정 파이썬에 있습니다. 당신이 말하는 것은 우리가 클래스 속성 이라고 부르는 입니다. 그들은 항상 클래스를 통해 행동하기 때문에 클래스의 문서 문자열 내에 문서화하는 것이 합리적이라는 것을 알았습니다. 이 같은:

class Albatross(object):
    """A bird with a flight speed exceeding that of an unladen swallow.

    Attributes:
        flight_speed     The maximum speed that such a bird can attain.
        nesting_grounds  The locale where these birds congregate to reproduce.
    """
    flight_speed = 691
    nesting_grounds = "Throatwarbler Man Grove"

나는 그것이 당신의 예에서 접근하는 것보다 눈에 훨씬 더 쉽다고 생각합니다. 문서 문자열에 속성 값의 복사본을 표시하려면 각 속성의 설명 옆이나 아래에 배치합니다.

Python에서 문서 문자열은 단순히 소스 코드 주석이 아니라 문서화하는 객체의 실제 구성원입니다. 클래스 속성 변수는 객체 자체가 아니라 객체에 대한 참조이므로 자체 문서 문자열을 보유 할 방법이 없습니다. 참조에 대한 문서 문자열에 대한 사례를 만들 수 있다고 생각합니다. 아마도 "실제로 여기에있는 내용"대신 "여기에 가야 할 내용"을 설명하기 위해 설명 할 수 있지만 포함하는 클래스 문서 문자열에서 쉽게 수행 할 수 있습니다.


대부분의 경우 이것은 괜찮다고 생각합니다. 속성 (용어 수정에 대한 감사)이 간결하게 선언되어 클래스 선언의 시작 부분에 그룹화 할 수 있기 때문에 둘 중 하나를 앞뒤로 뒤집는 것이 비현실적이지 않습니다. 문서 및 기본값} 또는 {문서 및 / 또는 기본값의 두 인스턴스 업데이트}.
intuited June

1
또한 내 예제는 속성에 대한 문서가 클래스의 독 스트링에 표시되도록합니다. 실제로 문서를 속성 자체의 독 스트링에 넣는 것을 선호하지만 대부분의 내장 유형에서는 작동하지 않습니다.
intuited

예, 내 초기 아이디어는 예를 들어 선언하는 것이 었습니다 flight_speed = 691; flight_speed.__doc__ = "blah blah". 나는 이것이 당신이 편집 에서 언급하고있는 것이라고 생각합니다 . 불행히도 (대부분?) 내장 유형의 인스턴스화에는 작동하지 않습니다 ( int예 : 사용자 정의 유형의 인스턴스화에 대해 작동합니다. =========== 실제로 클래스 / 모듈 속성에 대한 독 스트링 추가를 제안한 PEP (죄송합니다. 번호를 잊어 버림)가 있었지만 명확하게 할 수있는 방법을 찾지 못해 거부되었습니다. 독 스트링이 선행 또는 다음 속성에 대한 것인지 여부.
intuited

2
인스턴스 속성이면 어떨까요? 클래스 docstring에 여전히 문서화되어 있습니까?
n611x007

1
@intuited이 PEP 였나요? legacy.python.org/dev/peps/pep-0224
taz

30

당신은 PEP257을 인용 : 문서화 문자열 규칙을 섹션에 문서화 문자열은 무엇 가 적혀있다 :

Python 코드의 다른 곳에서 발생하는 문자열 리터럴도 문서 역할을 할 수 있습니다. 파이썬 바이트 코드 컴파일러에 의해 인식되지 않으며 런타임 객체 속성으로 액세스 할 수 없습니다 (예 : __doc__에 할당되지 않음). 그러나 소프트웨어 도구에서 두 가지 유형의 추가 독 스트링을 추출 할 수 있습니다.

모듈, 클래스 또는 __init__ 메소드의 최상위 레벨에서 단순 할당 직후에 발생하는 문자열 리터럴을 "속성 독 스트링"이라고합니다.

그리고 이것은 PEP 258 : 속성 독 스트링에 더 자세히 설명되어 있습니다. 위에서 설명한대로 ʇsәɹoɈ. 속성은 __doc__를 소유 할 수있는 객체가 아니므로 help()또는 pydoc에 나타나지 않습니다 . 이러한 독 스트링은 생성 된 문서에만 사용할 수 있습니다.

그들은 autoattribute 지시문 과 함께 Sphinx에서 사용됩니다.

Sphinx는 할당 앞 줄에 주석을 사용하거나 할당 뒤의 특수 주석 또는 자동 문서화 될 정의 뒤의 독 스트링을 사용할 수 있습니다.


1
jedi-vim 플러그인은 속성 독 스트링도 인식합니다.
Long Vu

1
이것이 언제 도입되었는지 모르겠지만 Sphinx 1.2.2는 생성 된 문서에 속성 독 스트링을 포함하는 것 같습니다.
jochen jul.

1
@jochen 감사합니다. 제 답변을 업데이트합니다.
marcz

3
PEP 258은 거부됩니다. 거부 통지에는 "이 문서는 현재 독립적 인 docutils에 대한 흥미로운 디자인 문서가 될 수 있지만 더 이상 표준 라이브러리에 포함될 예정이 아닙니다."
Michał Łazowik

13

이 효과에 속성을 남용 할 수 있습니다. 속성에는 getter, setter, deleter 및 docstring이 포함 됩니다. 순진하게도 이것은 매우 장황해질 것입니다.

class C:
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """Docstring goes here."""
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @x.deleter
    def x(self):
        del self._x

그러면 Cx에 속하는 독 스트링이 생깁니다.

In [24]: print(C.x.__doc__)
Docstring goes here.

많은 속성에 대해이 작업을 수행하는 것은 번거롭지 만 myprop 도우미 함수를 구상 할 수 있습니다.

def myprop(x, doc):
    def getx(self):
        return getattr(self, '_' + x)

    def setx(self, val):
        setattr(self, '_' + x, val)

    def delx(self):
        delattr(self, '_' + x)

    return property(getx, setx, delx, doc)

class C:
    a = myprop("a", "Hi, I'm A!")
    b = myprop("b", "Hi, I'm B!")

In [44]: c = C()

In [46]: c.b = 42

In [47]: c.b
Out[47]: 42

In [49]: print(C.b.__doc__)
Hi, I'm B!

그런 다음 Python을 대화 형으로 호출하면 다음 help이 제공됩니다.

Help on class C in module __main__:

class C
 |  Data descriptors defined here:
 |  
 |  a
 |      Hi, I'm A!
 |  
 |  b
 |      Hi, I'm B!

나는 당신이 추구하는 것과 거의 비슷하다고 생각합니다.

편집 : 이제 myprop내부 이름이 중요하지 않기 때문에 첫 번째 인수를 전혀 전달할 필요가 없다는 것을 알았습니다 . 후속 호출이 myprop어떻게 든 서로 통신 할 수 있다면 길고 가능성이 낮은 내부 속성 이름을 자동으로 결정할 수 있습니다. 나는 이것을 구현하는 방법이 있다고 확신하지만 그만한 가치가 있는지 확실하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.