developer tip

함수 내부에서 파이썬 함수의 Docstring을 인쇄하는 방법은 무엇입니까?

optionbox 2020. 12. 5. 09:40
반응형

함수 내부에서 파이썬 함수의 Docstring을 인쇄하는 방법은 무엇입니까?


함수 자체 내부에서 파이썬 함수의 독 스트링을 인쇄하고 싶습니다. 예를 들어.

def my_function(self):
  """Doc string for my function."""
  # print the Docstring here.

현재 나는 my_function정의 된 직후에 이것을하고 있습니다 .

print my_function.__doc__

그러나 차라리 함수가이 작업을 자체적으로 수행하도록합니다.

나는 호출 시도 print self.__doc__ print self.my_function.__doc__print this.__doc__내부 my_function을하지만이 작동하지 않았다.


def my_func():
    """Docstring goes here."""
    print my_func.__doc__

이것은 이름에 바인딩 된 개체를 변경하지 않는 한 작동합니다 my_func.

new_func_name = my_func
my_func = None

new_func_name()
# doesn't print anything because my_func is None and None has no docstring

이 작업을 수행하는 상황은 드물지만 발생합니다.

그러나 다음과 같은 데코레이터를 작성하면 :

def passmein(func):
    def wrapper(*args, **kwargs):
        return func(func, *args, **kwargs)
    return wrapper

이제 다음과 같이 할 수 있습니다.

@passmein
def my_func(me):
    print me.__doc__

그리고 이것은 당신의 함수가 self첫 번째 인자로 자신에 대한 참조를 얻 도록 할 것입니다. 그래서 그것은 항상 올바른 함수의 독 스트링을 얻을 수 있습니다. 메소드에서 사용하면 보통 self이 두 번째 인수가됩니다.


이것은 작동합니다 (내 테스트에서는 출력도 포함되어 있습니다). 아마도 __doc__getdoc 대신 사용할 수 있지만 나는 그것을 좋아하므로 내가 사용한 것입니다. 또한 클래스 / 메서드 / 함수 이름을 알 필요가 없습니다.

클래스, 메서드 및 함수에 대한 예제입니다. 당신이 찾고 있던 것이 아니라면 말 해주세요 :)

from inspect import *

class MySelfExplaningClass:
    """This is my class document string"""

    def __init__(self):
        print getdoc(self)

    def my_selfexplaining_method(self):
        """This is my method document string"""
        print getdoc(getattr(self, getframeinfo(currentframe()).function))


explain = MySelfExplaningClass()

# Output: This is my class document string

explain.my_selfexplaining_method()

# Output: This is my method document string

def my_selfexplaining_function():
    """This is my function document string"""
    print getdoc(globals()[getframeinfo(currentframe()).function])

my_selfexplaining_function()

# Output: This is my function document string

이것은 작동합니다 :

def my_function():
  """Docstring for my function"""
  #print the Docstring here.
  print my_function.__doc__

my_function()

Python 2.7.1에서

이것은 또한 작동합니다 :

class MyClass(object):
    def my_function(self):
        """Docstring for my function"""
        #print the Docstring here, either way works.
        print MyClass.my_function.__doc__
        print self.my_function.__doc__


foo = MyClass()

foo.my_function()

그러나 이것은 자체적으로 작동하지 않습니다.

class MyClass(object):
    def my_function(self):
        """Docstring for my function"""
        #print the Docstring here.
        print my_function.__doc__


foo = MyClass()

foo.my_function()

NameError : 전역 이름 'my_function'이 정의되지 않았습니다.


함수가 아닌 클래스 메서드처럼 질문을 제기했습니다. 여기서 네임 스페이스가 중요합니다. 함수의 경우 print my_function.__doc__my_function이 전역 네임 스페이스에 있으므로 괜찮습니다.

클래스 메서드의 경우 print self.my_method.__doc__갈 길입니다.

메서드의 이름을 지정하지 않고 변수를 전달하려는 경우 내장 함수 hasattr (object, attribute) 및 getattr (obj, attr)을 사용할 수 있습니다. 메서드의 이름이되는 문자열과 함께 변수를 전달할 수 있습니다. 예 :

class MyClass:
    def fn(self):
        """A docstring"""
        print self.fn.__doc__ 

def print_docstrings(object):
   for method in dir( object ):
       if method[:2] == '__':  # A protected function
           continue
       meth = getattr( object, method )
       if hasattr( meth , '__doc__' ):
           print getattr( meth , '__doc__' )

x = MyClass()
print_docstrings( x )

아직 아무도 언급하지 않은 아주 간단한 방법이 있습니다.

import inspect

def func():
    """Doc string"""
    print inspect.getdoc(func)

그리고 이것은 당신이 원하는 것을합니다.

여기에는 멋진 일이 없습니다. 일어나는 모든 일은 func.__doc__함수에서 수행함으로써 __doc__예상대로 작동 할 수있을 만큼 충분히 오래 속성 해결을 연기 한다는 것입니다.

콘솔 스크립트 진입 점을 위해 docopt와 함께 사용합니다.


시험:

class MyClass():
    # ...
    def my_function(self):
        """Docstring for my function"""
        print MyClass.my_function.__doc__
        # ...

(*) :뒤에 콜론 ( )이 누락되었습니다.my_function()


여러 번 언급했듯이 함수 이름을 사용하는 것은 globals () 디렉토리에서 동적 조회입니다. 정의 모듈에서만 작동하며 전역 기능에 대해서만 작동합니다. 멤버 함수의 문서 문자열을 찾으려면 클래스 이름에서 경로를 찾아야합니다.이 이름은 상당히 길어질 수 있으므로 상당히 번거 롭습니다.

def foo():
    """ this is foo """
    doc = foo.__doc__
class Foo:
    def bar(self):
       """ this is bar """
       doc = Foo.bar.__doc__

다음과 같다

def foo():
    """ this is foo """
    doc = globals()["foo"].__doc__
class Foo:
    def bar(self):
       """ this is bar """
       doc = globals()["Foo"].bar.__doc__

If you want to look up the doc string of the caller, that won't work anyway as your print-helper might live in a completely different module with a completely different globals() dictionary. The only correct choice is to look into the stack frame - but Python does not give you the function object being executed, it only has a reference to the "f_code" code object. But keep going, as there is also a reference to the "f_globals" of that function. So you can write a function to get the caller's doc like this, and as a variation from it, you get your own doc string.

import inspect

def get_caller_doc():
    frame = inspect.currentframe().f_back.f_back
    for objref in frame.f_globals.values():
        if inspect.isfunction(objref):
            if objref.func_code == frame.f_code:
                return objref.__doc__
        elif inspect.isclass(objref):
            for name, member in inspect.getmembers(objref):
                if inspect.ismethod(member):
                    if member.im_func.func_code == frame.f_code:
                        return member.__doc__

and let's go to test it:

def print_doc():
   print get_caller_doc()

def foo():
   """ this is foo """
   print_doc()

class Foo:
    def bar(self):
       """ this is bar """
       print_doc()

def nothing():
    print_doc()

class Nothing:
    def nothing(self):
        print_doc()

foo()
Foo().bar()

nothing()
Nothing().nothing()

# and my doc

def get_my_doc():
    return get_caller_doc()

def print_my_doc():
    """ showing my doc """
    print get_my_doc()

print_my_doc()

results in this output

 this is foo 
 this is bar 
None
None
 showing my doc 

Actually, most people want their own doc string only to hand it down as an argument, but the called helper function can look it up all on its own. I'm using this in my unittest code where this is sometimes handy to fill some logs or to use the doc string as test data. That's the reason why the presented get_caller_doc() only looks for global test functions and member functions of a test class, but I guess that is enough for most people who want to find out about the doc string.

class FooTest(TestCase):
    def get_caller_doc(self):
        # as seen above
    def test_extra_stuff(self):
        """ testing extra stuff """
        self.createProject("A")
    def createProject(self, name):
        description = self.get_caller_doc()
        self.server.createProject(name, description)

To define a proper get_frame_doc(frame) with sys._getframe(1) is left to the reader().


inserting print __doc__ just after the class declaration,, before the def __init__, will print the doc string to the console every time you initiate an object with the class

참고URL : https://stackoverflow.com/questions/8822701/how-to-print-docstring-of-python-function-from-inside-the-function-itself

반응형