Python 클래스 상속에서 독 스트링 상속


97

파이썬에서 클래스 상속을 시도하고 있습니다. 각 클래스와 상속 된 클래스가 좋은 독 스트링을 갖기를 바랍니다. 따라서 상속 된 클래스에 대해 다음과 같이하고 싶습니다.

  • 기본 클래스 독 스트링 상속
  • docstring에 관련 추가 문서를 추가 할 수 있습니다.

클래스 상속 상황에서 이런 종류의 독 스트링 조작을 수행하는 (아마도 우아하거나 비단뱀 같은) 방법이 있습니까? 다중 상속은 어떻습니까?


2
불행히도 질문이 닫 혔기 때문에 대답 할 수 없지만 Python 3.5에서는 inspect.getdoc독 스트링을 찾을 때까지 상속 트리를 검색합니다.
gerrit

1
이 답변을 참조하십시오 .
gerrit

답변:


39

당신은 유일한 사람이 아닙니다! comp.lang.python얼마 전에 이에 대한 논의가 있었고 레시피가 만들어졌습니다. 여기에서 확인 하십시오 .

"""
doc_inherit decorator

Usage:

class Foo(object):
    def foo(self):
        "Frobber"
        pass

class Bar(Foo):
    @doc_inherit
    def foo(self):
        pass 

Now, Bar.foo.__doc__ == Bar().foo.__doc__ == Foo.foo.__doc__ == "Frobber"
"""

from functools import wraps

class DocInherit(object):
    """
    Docstring inheriting method descriptor

    The class itself is also used as a decorator
    """

    def __init__(self, mthd):
        self.mthd = mthd
        self.name = mthd.__name__

    def __get__(self, obj, cls):
        if obj:
            return self.get_with_inst(obj, cls)
        else:
            return self.get_no_inst(cls)

    def get_with_inst(self, obj, cls):

        overridden = getattr(super(cls, obj), self.name, None)

        @wraps(self.mthd, assigned=('__name__','__module__'))
        def f(*args, **kwargs):
            return self.mthd(obj, *args, **kwargs)

        return self.use_parent_doc(f, overridden)

    def get_no_inst(self, cls):

        for parent in cls.__mro__[1:]:
            overridden = getattr(parent, self.name, None)
            if overridden: break

        @wraps(self.mthd, assigned=('__name__','__module__'))
        def f(*args, **kwargs):
            return self.mthd(*args, **kwargs)

        return self.use_parent_doc(f, overridden)

    def use_parent_doc(self, func, source):
        if source is None:
            raise NameError, ("Can't find '%s' in parents"%self.name)
        func.__doc__ = source.__doc__
        return func

doc_inherit = DocInherit 

메서드가 부모 클래스의 메서드의 독 스트링을 상속하는 것은 깔끔합니다. 그것은 많은 경우에 유용 할 것이라고 생각합니다. 나는 상속하고 추가하고 싶은 전체 클래스의 독 스트링에 대해 더 많이 생각하고 있었다.
Craig McQueen

아, 잡았다. 이 경우 대부분의 문서 생성은 이미이를 수행합니다.
John Feminella

36

독 스트링을 쉽게 연결할 수 있습니다.

class Foo(object):
    """
    Foo Class.
    This class foos around.
    """
    pass

class Bar(Foo):
    """
    Bar class, children of Foo
    Use this when you want to Bar around.
    parent:
    """ 
    __doc__ += Foo.__doc__
    pass

그러나 그것은 쓸모가 없습니다. 대부분의 문서 생성 도구 ( SphinxEpydoc 포함)는 메서드를 포함하여 이미 상위 docstring을 가져옵니다. 따라서 아무것도 할 필요가 없습니다.


16
실제로 대부분의 문서화 도구가 그렇게합니다. 그러나 내장 된 help () 함수는 그렇지 않습니다.
MarioVilas 2013 년

2
@MarioVilas :보고해야 할 버그일까요?
naught101

스핑크스는 저를 위해 그렇게하지 않는 것 같습니다. 아마도 제 부모님이 "비공개"라는 이름이 밑줄로 시작하기 때문일 것입니다.
Gringo Suave

6

특히 우아하지는 않지만 단순하고 직접적입니다.

class X(object):
  """This class has a method foo()."""
  def foo(): pass

class Y(X):
  __doc__ = X.__doc__ + ' Also bar().'
  def bar(): pass

지금:

>>> print Y.__doc__
This class has a method foo(). Also bar().

이 작업을 수행하려는 경우 Init docstring정의에서 수행하는 방법이 Y있습니까? 내가 할 수 있었던 유일한 방법 __init__.__doc__ = X.__init__.__doc__ + " Also another param"__init__정의 를 따르는 Y것이지만 이것은 서식을 엉망으로 만들어 여분의 공백을 유발하는 것 같습니다.
mgilbert

5

상속 된 독 스트링 구문과 선호하는 순서를 모두 보존 할 수있는 혼합 스타일은 다음과 같습니다.

class X(object):
  """This class has a method foo()."""
  def foo(): pass

class Y(X):
  """ Also bar()."""
  __doc__ = X.__doc__ + __doc__
  def bar(): pass

Alex의 출력과 동일한 출력 :

>>> print Y.__doc__
This class has a method foo(). Also bar().

얇은 얼음 : 독 스트링을 사용하면 python -OO에서 모듈을 사용할 수 없게 될 수 있습니다 .

TypeError: cannot concatenate 'str' and 'NoneType' objects

4

나는 custom_inherit를 썼다 상속을 처리하기위한 간단하고 가벼운 도구를 제공하기 위해 를 .

또한 다양한 유형의 독 스트링 (예 : Numpy, Google 및 reST 형식의 독 스트링)을 병합하기위한 멋진 기본 스타일도 제공됩니다. 자신 만의 스타일을 매우 쉽게 제공 할 수도 있습니다.

겹치는 독 스트링 섹션은 자식의 섹션으로 연기됩니다. 그렇지 않으면 멋진 형식으로 병합됩니다.

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