How to print Docstring of python function from inside the function itself?

后端 未结 8 1628
無奈伤痛
無奈伤痛 2020-12-04 23:26

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

def my_function(self):
  \"\"\"Doc string for my function.\"\"\"
         


        
相关标签:
8条回答
  • 2020-12-04 23:54
    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.

    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.

    0 讨论(0)
  • 2020-12-05 00:02

    This works:

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

    in 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

    0 讨论(0)
  • 2020-12-05 00:02

    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

    0 讨论(0)
  • 2020-12-05 00:06

    Try:

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

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

    0 讨论(0)
  • 2020-12-05 00:08

    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:

    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.

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

    0 讨论(0)
  • 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.

    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
    
    0 讨论(0)
提交回复
热议问题