For teaching purposes I want an IPython notebook that displays (as output from a cell) the function source code, but I want to be able to reference this in multiple notebooks. Hence I would like to display the function code, in a similar way to using the %psource magic, but appropriately syntax highlighted.
This is a similar question to this question, but I want to be able to apply it to a single function within a file, rather than to the complete file at once.
Using the suggestion from the previous question I hacked a short code that works in simple cases:
def print_source(module, function):
"""For use inside an IPython notebook: given a module and a function, print the source code."""
from inspect import getmembers, isfunction, getsource
from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import HtmlFormatter
from IPython.core.display import HTML
internal_module = __import__(module)
internal_functions = dict(getmembers(internal_module, isfunction))
return HTML(highlight(getsource(internal_functions[function]), PythonLexer(), HtmlFormatter(full=True)))
Two questions:
- This gist suggests that showing the whole function could be done by defining appropriate cell magic. Is it possible to define an appropriate cell magic to just show a single function, as above?
- Is there a way of doing this without importing the entire module, or a more robust way of doing this?
1) Magics are just simple function not difficult to define, you could have a look here
Customizing IPython - Config.ipynb
if I remember correctly. still I'm not sure it is worth definig a magic in your case.2) Most of the time, no. You have to import the module as we need live code to know where it is defined.
In general, finding the code of a function is not always super easy. On python 3 you can always access the code object, but most of the time, as soon as you have things like decorated function, or dynamically generated function, it becomes difficult. I suppose you could also inspire from
psource
/pinfo2
and have them return info instead of paging it.