In Julia, calling a function with the @edit
macro from the REPL will open the editor and put the cursor at the line where the method is defined. So, doing this:
julia> @edit 1 + 1
jumps to julia/base/int.jl
and puts the cursor on the line:
(+)(x::T, y::T) where {T<:BitInteger} = add_int(x, y)
As does the function form: edit(+, (Int, Int))
Is there an equivalent decorator/function in Python that does the same from the Python REPL?
Advertisement
Answer
Disclaimer: In the Python ecosystem, this is not the job of the core language/runtime but rather tools such as IDEs. For example, the ipython shell has the ??
special syntax to get improved help including source code.
Python 3.8.5 (default, Jul 21 2020, 10:42:08) Type 'copyright', 'credits' or 'license' for more information IPython 7.18.1 -- An enhanced Interactive Python. Type '?' for help. In [1]: import random In [2]: random.uniform?? Signature: random.uniform(a, b) Source: def uniform(self, a, b): "Get a random number in the range [a, b) or [a, b] depending on rounding." return a + (b-a) * self.random() File: /usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/random.py Type: method
The Python runtime itself allows viewing source code of objects via inspect.getsource
. This uses a heuristic to search the source code as available; the objects themselves do not carry their source code.
Python 3.8.5 (default, Jul 21 2020, 10:42:08) [Clang 11.0.0 (clang-1100.0.33.17)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import inspect >>> print(inspect.getsource(inspect.getsource)) def getsource(object): """Return the text of the source code for an object. The argument may be a module, class, method, function, traceback, frame, or code object. The source code is returned as a single string. An OSError is raised if the source code cannot be retrieved.""" lines, lnum = getsourcelines(object) return ''.join(lines)
It is not possible to resolve arbitrary expressions or statements to their source; since all names in Python are resolved dynamically, the vast majority of expressions does not have a well-defined implementation unless executed. A debugger, e.g. as provided by pdb.set_trace()
, allows inspecting the expression as it is executed.