Can Python print a function definition?

Question:

In JavaScript, one can print out the definition of a function. Is there a way to accomplish this in Python?

(Just playing around in interactive mode, and I wanted to read a module without open(). I was just curious).

Asked By: Eddie Welker

||

Answers:

If you’re using iPython, you can use function_name? to get help, and function_name?? will print out the source, if it can.

Answered By: Peter

If you are importing the function, you can use inspect.getsource:

>>> import re
>>> import inspect
>>> print inspect.getsource(re.compile)
def compile(pattern, flags=0):
    "Compile a regular expression pattern, returning a pattern object."
    return _compile(pattern, flags)

This will work in the interactive prompt, but apparently only on objects that are imported (not objects defined within the interactive prompt). And of course it will only work if Python can find the source code (so not on built-in objects, C libs, .pyc files, etc)

Answered By: Kenan Banks

You can use the __doc__ keyword:

#print the class description
print string.__doc__
#print function description
print open.__doc__
Answered By: Amirshk

While I’d generally agree that inspect is a good answer, I’d disagree that you can’t get the source code of objects defined in the interpreter. If you use dill.source.getsource from dill, you can get the source of functions and lambdas, even if they are defined interactively.
It also can get the code for from bound or unbound class methods and functions defined in curries… however, you might not be able to compile that code without the enclosing object’s code.

>>> from dill.source import getsource
>>> 
>>> def add(x,y):
...   return x+y
... 
>>> squared = lambda x:x**2
>>> 
>>> print getsource(add)
def add(x,y):
  return x+y

>>> print getsource(squared)
squared = lambda x:x**2

>>> 
>>> class Foo(object):
...   def bar(self, x):
...     return x*x+x
... 
>>> f = Foo()
>>> 
>>> print getsource(f.bar)
def bar(self, x):
    return x*x+x

>>> 
Answered By: Mike McKerns

You can use the __doc__ in the function, take hog() function as example:
You can see the usage of hog() like this:

from skimage.feature import hog

print hog.__doc__

The output will be:

Extract Histogram of Oriented Gradients (HOG) for a given image.
Compute a Histogram of Oriented Gradients (HOG) by

    1. (optional) global image normalisation
    2. computing the gradient image in x and y
    3. computing gradient histograms
    4. normalising across blocks
    5. flattening into a feature vector

Parameters
----------
image : (M, N) ndarray
    Input image (greyscale).
orientations : int
    Number of orientation bins.
pixels_per_cell : 2 tuple (int, int)
    Size (in pixels) of a cell.
cells_per_block  : 2 tuple (int,int)
    Number of cells in each block.
visualise : bool, optional
    Also return an image of the HOG.
transform_sqrt : bool, optional
    Apply power law compression to normalise the image before
    processing. DO NOT use this if the image contains negative
    values. Also see `notes` section below.
feature_vector : bool, optional
    Return the data as a feature vector by calling .ravel() on the result
    just before returning.
normalise : bool, deprecated
    The parameter is deprecated. Use `transform_sqrt` for power law
    compression. `normalise` has been deprecated.

Returns
-------
newarr : ndarray
    HOG for the image as a 1D (flattened) array.
hog_image : ndarray (if visualise=True)
    A visualisation of the HOG image.

References
----------
* http://en.wikipedia.org/wiki/Histogram_of_oriented_gradients

* Dalal, N and Triggs, B, Histograms of Oriented Gradients for
  Human Detection, IEEE Computer Society Conference on Computer
  Vision and Pattern Recognition 2005 San Diego, CA, USA

Notes
-----
Power law compression, also known as Gamma correction, is used to reduce
the effects of shadowing and illumination variations. The compression makes
the dark regions lighter. When the kwarg `transform_sqrt` is set to
``True``, the function computes the square root of each color channel
and then applies the hog algorithm to the image.
Answered By: startag.cv

This is the way I figured out how to do it:

    import inspect as i
    import sys
    sys.stdout.write(i.getsource(MyFunction))

This takes out the new line characters and prints the function out nicely

Answered By: Steve

Use help(function) to get the function description.

You can read more about help() here.

Answered By: Safwan

If you are importing the function, you can use inspect.getsource. This will work in the interactive prompt, but apparently only on objects that are imported (not objects defined within the interactive prompt)

It also doesn’t work on many types of dynamically executed code, such as with exec(). In Python v3.3+, you can use inspect.signature(). It appers this is what help() also uses internally. This also works with interactively defined things.

Example:

import inspect

code = """
def sum(a:int, b_int=5) -> int:
  return a + b
"""

exec(code)
print(sum(2))
print("def sum{}".format(inspect.signature(sum)))

This results in:

7
def sum(a: int, b: int = 5) -> int

Side-note: Yes, exec() is dangerous. If you don’t know why, you shouldn’t use it. It’s used here purely for demonstration purposes.

Answered By: Ferry Boender

I know this question is old, but I just wanted to clarify a few things.

I Googled for a solution for the problem and discovered this question, and I found in IPython you can use inspect.getsource to get functions defined in the interpreter.

But you can’t use it to get definitions of functions defined interactively in the plain Python shell (i.e. Python.exe).

IPython 8.4.0 on Python 3.10.5

Python 3.10.5 (tags/v3.10.5:f377153, Jun  6 2022, 16:14:13) [MSC v.1929 64 bit (AMD64)] on win32
Type 'copyright', 'credits' or 'license' for more information
IPython 8.4.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import inspect
   ...: def fibonacci(n):
   ...:     s = []
   ...:     a, b = 0, 1
   ...:     for i in range(n):
   ...:         s.append(a)
   ...:         a, b = b, a + b
   ...:     return s
   ...:
   ...: fibonacci(16)
Out[1]: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

In [2]: print(inspect.getsource(fibonacci))
def fibonacci(n):
    s = []
    a, b = 0, 1
    for i in range(n):
        s.append(a)
        a, b = b, a + b
    return s

Python 3.10.5

Python 3.10.5 (tags/v3.10.5:f377153, Jun  6 2022, 16:14:13) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import inspect
>>> def fibonacci(n):
...     s = []
...     a, b = 0, 1
...     for i in range(n):
...         s.append(a)
...         a, b = b, a + b
...     return s
...
>>> fibonacci(16)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
>>> print(inspect.getsource(fibonacci))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:Program FilesPython310libinspect.py", line 1147, in getsource
    lines, lnum = getsourcelines(object)
  File "C:Program FilesPython310libinspect.py", line 1129, in getsourcelines
    lines, lnum = findsource(object)
  File "C:Program FilesPython310libinspect.py", line 958, in findsource
    raise OSError('could not get source code')
OSError: could not get source code
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.