I have the following function:
def my_func():
"""My docstring is both funny and informative"""
pass
How do I get access to the docstring?
I have the following function:
def my_func():
"""My docstring is both funny and informative"""
pass
How do I get access to the docstring?
Interactively, you can display it with:
help(my_func)
Or from code you can retrieve it with (surround it with print(.) to get a formatted output):
my_func.__doc__
print(func.__doc__); I find it more useful while in the CLI, easy to go back to the func's signature when needed.You can also use inspect.getdoc. It cleans up the __doc__ by normalizing tabs to spaces and left shifting the doc body to remove common leading spaces.
__doc__ ?The ast module can be used to parse a file with python code and build an "Abstract Syntax Tree" for it. Then one can "walk" that to extract docstrings, and process/present them as desired
import ast
import sys
f = open(sys.argv[1], "r") #filename input
module = ast.parse(f.read())
class_definitions = [node for node in module.body if isinstance(node, ast.ClassDef)]
method_definitions = []
for class_def in class_definitions:
print(class_def.name)
print(ast.get_docstring(class_def))
function_definitions = [node for node in class_def.body if isinstance(node, ast.FunctionDef)]
for f in function_definitions:
print('\t---')
print('\t'+f.name)
print('\t---')
print('\t'+'\t'.join(ast.get_docstring(f).splitlines(True)))
print('----')
If inside a class you can also do something like this:
import sys
class A(object):
""" A class """
def func_values(self):
fn_name = sys._getframe(1).f_code.co_name
fn_doc = eval(f"self.{fn_name}.__doc__") or 'N/A'
return (fn_name, fn_doc)
def func_A(self):
# handle NO docstring
name, docstring = self.func_values()
print(name, '=>', docstring)
def func_B(self):
""" This is function B which has a docstring """
name, docstring = self.func_values()
print(name, "=>", docstring)
a = A()
a.func_A()
a.func_B()
eval seems unnecessarily complicated. self.func_A.__doc__ works equally well. At least when you call it inside a method, its own name is always known. Of course you cannot just copy-paste the code...self.func_A or self.func_B - the function name is dynamic ... this is why the eval