如何从函数本身内部打印python函数的Docstring?
我想从函数本身内部打印python函数的docstring。 例如 目前,我是在定义了如何从函数本身内部打印python函数的Docstring?,python,function,printing,docstring,Python,Function,Printing,Docstring,我想从函数本身内部打印python函数的docstring。 例如 目前,我是在定义了我的_函数之后直接执行此操作的 print my_function.__doc__ 但我宁愿让函数自己做这件事 我已尝试调用print self.\uuuu doc\uuuuuprint self.my\u函数.\uuu doc\uuuu和打印此文件。\uu doc\uuuuu在我的\u函数中,但这不起作用。尝试: class MyClass(): # ... def my_function(
我的_函数之后直接执行此操作的
print my_function.__doc__
但我宁愿让函数自己做这件事
我已尝试调用print self.\uuuu doc\uuuuu
print self.my\u函数.\uuu doc\uuuu
和打印此文件。\uu doc\uuuuu
在我的\u函数中,但这不起作用。尝试:
class MyClass():
# ...
def my_function(self):
"""Docstring for my function"""
print MyClass.my_function.__doc__
# ...
(*)在my_function()
之后缺少一个冒号(:
)此操作:
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()
名称错误:未定义全局名称“my_function”您提出的问题像是类方法而不是函数。名称空间在这里很重要。对于函数,print my_function.\uuuu doc\uu
可以,因为my_函数位于全局命名空间中
对于一个类方法,那么打印self.my\u方法.\uuuuu doc\uuuu
将是一个不错的选择
如果您不想指定方法的名称,而是想向其传递一个变量,那么可以使用内置函数hasattr(object,attribute)和getattr(obj,attr),这两个函数按照它们所说的操作,允许您传递变量,字符串是方法的名称。e、 g
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 )
只要您不更改绑定到名称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
)作为其第一个参数,因此它始终可以获得正确函数的docstring。如果在方法上使用,通常的self
将成为第二个参数。这应该有效(在我的测试中,它也包括输出)。你可能会用\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。此外,这并不要求您知道类/方法/函数的名称
类、方法和函数的示例。如果不是你想要的,告诉我:)
如前所述,使用函数名是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__
如果要查找调用者的文档字符串,这无论如何都不会起作用,因为您的打印助手可能位于一个完全不同的模块中,该模块具有完全不同的globals()字典。唯一正确的选择是查看堆栈框架——但是Python没有给您正在执行的函数对象,它只引用了“f_code”代码对象。但请继续,因为还有一个对该函数的“f_globals”的引用。因此,您可以编写一个函数,像这样获取调用方的文档,作为其变体,您可以获得自己的文档字符串
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__
让我们来测试一下:
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
实际上,大多数人只希望自己的doc字符串作为参数传递,但是被调用的helper函数可以自己查找它。我在我的unittest代码中使用了它,有时它可以方便地填充一些日志或使用文档字符串作为测试数据。这就是为什么现在的get_caller_doc()只查找全局测试函数和测试类的成员函数的原因,但是我想对于大多数想了解doc字符串的人来说,这已经足够了
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定义适当的get\u frame\u doc(frame).\u getframe(1)留给reader()。有一个非常简单的方法,但还没有人提到:
import inspect
def func():
"""Doc string"""
print inspect.getdoc(func)
这就是你想要的
这里没有什么稀奇古怪的事。所发生的一切是,通过在函数中执行func.\uuuuu doc\uuuuu
延迟属性解析足够长的时间,以便在其上查找\uuuuuu doc\uuu
,正如您所期望的那样
我使用docopt作为控制台脚本入口点。插入
print\uuuuu doc\uuuuuu
在类声明之后,def\uu init\uuuuu
之前,每次使用类启动对象时,都会将文档字符串打印到控制台对不起,伙计们,我的愚蠢自我。我的函数。\uu doc\uu实际上起作用。您的类方法只起作用,因为您以前在全局命名空间中将我的函数定义为函数。用一个新的python实例试试;)@你没有测试你的第二个代码片段。没有work@AlexLeach您是否使用类测试了代码段?事实上,它不起作用……@jgritty和alexleach。类中定义的id为est函数的方法无法知道它们的外部空间。看这个问题()和我对它的回答不,我没有,但我认为jgritty可能已经做到了。只是做了测试,它工作正常,正如预期的那样(更改方法的docstring,仍然打印函数docstring)。模块中定义的函数在类方法中可用。e、 g.如果类方法是在脚本顶部导入的,则无需在类方法中重新导入。有没有好的方法不必重复方法名称本身?像这样的东西。医生还是什么?对不起,我是python新手。是的,不是真的。。我通过dir(self.my_函数)和self.my_函数查看了一下。self.my_函数看上去可能很有趣,但仍然需要通过该对象模型访问它。您可以为dir(MyClass)中的方法添加如下函数::如果hasattr(getattr(MyClass,method),“\uuu doc\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。我会把它放在我的原始答案中…@shane87,AlexLeach和Mattloungo:请看我的答案
this is foo
this is bar
None
None
showing my doc
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)
import inspect
def func():
"""Doc string"""
print inspect.getdoc(func)