如何从函数本身内部打印python函数的Docstring?

时间:2021-12-13 22:05:23

I want to print the docstring of a python function from inside the function itself. for eg.

我想从函数本身内部打印python函数的docstring。例如。

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

At the moment I am doing this directly after my_function has been defined.

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

print my_function.__doc__

But would rather let the function do this itself.

但宁愿让函数自己这样做。

I have tried calling print self.__doc__ print self.my_function.__doc__ and print this.__doc__ inside my_function but this did not work.

我试过调用print self .__ doc__ print self.my_function .__ doc__并在my_function中打印这个.__ doc__但是这不起作用。

8 个解决方案

#1


51  

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

This will work as long as you don't change the object bound to the name my_func.

只要您不更改绑定到名称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

Situations in which you'd do this are rather rare, but they do happen.

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

However, if you write a decorator like this:

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

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

Now you can do this:

现在你可以这样做:

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

And this will ensure that your function gets a reference to itself (similar to self) as its first argument, so it can always get the docstring of the right function. If used on a method, the usual self becomes the second argument.

这将确保您的函数获得对其自身(类似于self)的引用作为其第一个参数,因此它始终可以获得正确函数的文档字符串。如果在方法上使用,则通常的self成为第二个参数。

#2


7  

This should work (in my tests it does, also included output). You could probably use __doc__ instead of getdoc, but I like it, so thats just what i used. Also, this doesn't require you to know the names of the class/method/function.

这应该工作(在我的测试中,它也包括输出)。您可以使用__doc__而不是getdoc,但我喜欢它,所以这就是我使用的。此外,这不需要您知道类/方法/函数的名称。

Examples both for a class, a method and a function. Tell me if it's not what you were looking for :)

类,方法和函数的示例。告诉我,如果它不是你想要的:)

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

#3


4  

This works:

这有效:

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

my_function()

in Python 2.7.1

在Python 2.7.1中

This also works:

这也有效:

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

This however, will not work on its own:

但是,这不会单独工作:

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: global name 'my_function' is not defined

NameError:未定义全局名称“my_function”

#4


2  

You've posed your question like a class method rather than a function. Namespaces are important here. For a function, print my_function.__doc__ is fine, as my_function is in the global namespace.

你提出的问题就像一个类方法而不是一个函数。命名空间在这里很重要。对于函数,打印my_function .__ doc__很好,因为my_function在全局命名空间中。

For a class method, then print self.my_method.__doc__ would be the way to go.

对于类方法,然后打印self.my_method .__ doc__将是要走的路。

If you don't want to specify the name of the method, but rather pass a variable to it, you can use the built-in functions hasattr(object,attribute) and getattr(obj,attr), which do as they say, allowing you to pass variables in with strings being the name of a method. e.g.

如果你不想指定方法的名称,而是将变量传递给它,你可以使用内置函数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 )

#5


2  

There's quite a simple method for doing this that nobody has mentioned yet:

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

import inspect

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

And this does what you want.

这就是你想要的。

There's nothing fancy going on here. All that's happening is that by doing func.__doc__ in a function defers attribute resolution long enough to have looking up __doc__ on it work as you'd expect.

这里没有什么花哨的东西。所有发生的事情都是通过在函数中执行func .__ doc__将属性解析推迟到足以让它查找__doc__就像你期望的那样工作。

I use this with docopt for console script entry points.

我使用docopt作为控制台脚本入口点。

#6


1  

Try:

尝试:

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

(*) There was a colon (:) missing after my_function()

(*)my_function()后缺少一个冒号(:)

#7


1  

As noted many times, using the function name is a dynamic lookup in the globals() directory. It only works in the module of the definition and only for a global function. If you want to find out the doc string of a member function, you would need to also lookup the path from the class name - which is quite cumbersome as these names can get quite long:

如前所述,使用函数名称是globals()目录中的动态查找。它仅适用于定义的模块,仅适用于全局功能。如果你想找出一个成员函数的doc字符串,你还需要从类名中查找路径 - 这非常麻烦,因为这些名称可能会很长:

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

is equivalent to

相当于

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.

如果你想查找调用者的doc字符串,那么无论如何都不会起作用,因为你的print-helper可能生活在一个完全不同的模块中,并且有一个完全不同的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__

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.

实际上,大多数人只想将自己的文档字符串作为参数传递给它,但是被调用的辅助函数可以单独查找它。我在我的unittest代码中使用它,这有时很方便填写一些日志或使用doc字符串作为测试数据。这就是为什么所提出的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)

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

使用sys._getframe(1)定义正确的get_frame_doc(帧)留给reader()。

#8


0  

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

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

#1


51  

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

This will work as long as you don't change the object bound to the name my_func.

只要您不更改绑定到名称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

Situations in which you'd do this are rather rare, but they do happen.

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

However, if you write a decorator like this:

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

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

Now you can do this:

现在你可以这样做:

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

And this will ensure that your function gets a reference to itself (similar to self) as its first argument, so it can always get the docstring of the right function. If used on a method, the usual self becomes the second argument.

这将确保您的函数获得对其自身(类似于self)的引用作为其第一个参数,因此它始终可以获得正确函数的文档字符串。如果在方法上使用,则通常的self成为第二个参数。

#2


7  

This should work (in my tests it does, also included output). You could probably use __doc__ instead of getdoc, but I like it, so thats just what i used. Also, this doesn't require you to know the names of the class/method/function.

这应该工作(在我的测试中,它也包括输出)。您可以使用__doc__而不是getdoc,但我喜欢它,所以这就是我使用的。此外,这不需要您知道类/方法/函数的名称。

Examples both for a class, a method and a function. Tell me if it's not what you were looking for :)

类,方法和函数的示例。告诉我,如果它不是你想要的:)

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

#3


4  

This works:

这有效:

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

my_function()

in Python 2.7.1

在Python 2.7.1中

This also works:

这也有效:

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

This however, will not work on its own:

但是,这不会单独工作:

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: global name 'my_function' is not defined

NameError:未定义全局名称“my_function”

#4


2  

You've posed your question like a class method rather than a function. Namespaces are important here. For a function, print my_function.__doc__ is fine, as my_function is in the global namespace.

你提出的问题就像一个类方法而不是一个函数。命名空间在这里很重要。对于函数,打印my_function .__ doc__很好,因为my_function在全局命名空间中。

For a class method, then print self.my_method.__doc__ would be the way to go.

对于类方法,然后打印self.my_method .__ doc__将是要走的路。

If you don't want to specify the name of the method, but rather pass a variable to it, you can use the built-in functions hasattr(object,attribute) and getattr(obj,attr), which do as they say, allowing you to pass variables in with strings being the name of a method. e.g.

如果你不想指定方法的名称,而是将变量传递给它,你可以使用内置函数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 )

#5


2  

There's quite a simple method for doing this that nobody has mentioned yet:

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

import inspect

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

And this does what you want.

这就是你想要的。

There's nothing fancy going on here. All that's happening is that by doing func.__doc__ in a function defers attribute resolution long enough to have looking up __doc__ on it work as you'd expect.

这里没有什么花哨的东西。所有发生的事情都是通过在函数中执行func .__ doc__将属性解析推迟到足以让它查找__doc__就像你期望的那样工作。

I use this with docopt for console script entry points.

我使用docopt作为控制台脚本入口点。

#6


1  

Try:

尝试:

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

(*) There was a colon (:) missing after my_function()

(*)my_function()后缺少一个冒号(:)

#7


1  

As noted many times, using the function name is a dynamic lookup in the globals() directory. It only works in the module of the definition and only for a global function. If you want to find out the doc string of a member function, you would need to also lookup the path from the class name - which is quite cumbersome as these names can get quite long:

如前所述,使用函数名称是globals()目录中的动态查找。它仅适用于定义的模块,仅适用于全局功能。如果你想找出一个成员函数的doc字符串,你还需要从类名中查找路径 - 这非常麻烦,因为这些名称可能会很长:

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

is equivalent to

相当于

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.

如果你想查找调用者的doc字符串,那么无论如何都不会起作用,因为你的print-helper可能生活在一个完全不同的模块中,并且有一个完全不同的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__

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.

实际上,大多数人只想将自己的文档字符串作为参数传递给它,但是被调用的辅助函数可以单独查找它。我在我的unittest代码中使用它,这有时很方便填写一些日志或使用doc字符串作为测试数据。这就是为什么所提出的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)

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

使用sys._getframe(1)定义正确的get_frame_doc(帧)留给reader()。

#8


0  

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

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