如何从函数本身打印Python函数的Docstring?

我想从函数内部打印一个Python函数的文档string。 例如。

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

目前我正在定义my_function之后直接执行此操作。

 print my_function.__doc__ 

但宁愿让function自己做。

我曾尝试调用print self.__doc__ print self.my_function.__doc__并在my_function中print this.__doc__ ,但是这不起作用。

 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 

你这样做的情况相当less见,但确实发生了。

但是,如果你写这样一个装饰器:

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

现在你可以做到这一点:

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

这将确保您的函数获取对自身的引用(类似于self )作为它的第一个参数,所以它总是可以获得正确函数的文档string。 如果在方法上使用,通常的self会成为第二个参数。

这应该工作(在我的testing中,也包括输出)。 你可以使用__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__将是要走的路。

如果你不想指定方法的名字,而是传递一个variables,你可以使用内build函数hasattr(object,attribute)和getattr(obj,attr)允许你使用string作为方法的名称来传递variables。 例如

 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 ) 

尝试:

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

(*) my_function()之后冒号( my_function()缺失

有一个很简单的方法来做到这一点,没有人提到过:

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

这就是你想要的。

这里没什么特别的。 所有这一切都是通过在一个函数中执行func.__doc__来延缓属性的parsing,足够长的时间来查找__doc__ ,就像你期望的那样。

我用这个与docopt控制台脚本入口点。

正如多次提到的那样,使用函数名称是globals()目录中的dynamic查找。 它只能在定义的模块中工作,只能在全局函数中使用。 如果你想find一个成员函数的文档string,你还需要从类名称中查找path – 这很麻烦,因为这些名字可能会变得很长:

 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__ 

如果你想查找调用者的文档string,那么这将不起作用,因为你的打印助手可能与完全不同的globals()字典完全不同。 唯一正确的select是查看堆栈框架 – 但是Python不会给你正在执行的函数对象,它只是对“f_code”代码对象的引用。 但继续下去,因为这个函数的“f_globals”也是有参考的。 所以你可以编写一个函数来获取调用者的文档,并从中获取你自己的文档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__ 

让我们去testing它:

 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() 

导致这个输出

  this is foo this is bar None None showing my doc 

实际上,大多数人都希望自己的文档string只是把它作为一个参数来传递,而被调用的帮助函数可以单独查看它们。 我在我的unit testing代码中使用它,有时候这样做可以方便地填充一些日志或者使用docstring作为testing数据。 这就是为什么提供的get_caller_doc()只能查找testing类的全局testing函数和成员函数的原因,但是我想这对于大多数想要了解文档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) 

用sys._getframe(1)定义一个合适的get_frame_doc(frame)留给reader()。

在类声明后面插入print __doc__ ,在def __init__之前,每次用类启动一个对象时,都会将docstring打印到控制台