A variant over the one suggested by omri-saadon, is to use inspect.getframeinfo which lists the code_context.
import inspect
def debug(*args):
try: # find code_context
# First try to use currentframe() (maybe not available all implementations)
frame = inspect.currentframe()
if frame:
# Found a frame, so get the info, and strip space from the code_context
code_context = inspect.getframeinfo(frame.f_back).code_context[0].strip()
else:
# No frame, so use stack one level above us, and strip space around
# the 4th element, code_context
code_context = inspect.stack()[1][4][0].strip()
finally:
# Deterministic free references to the frame, to be on the safe side
del frame
print('Code context: {}'.format(code_context))
print('Actual arguments: {}'.format(args))
## Test code to have something to output #########
def my_seventh():
return 7
a = 0.2
b = 1.2
c = a + 1
my_eight = my_seventh
debug(a, b, c, b+2)
debug([4.1, 4.2], (5.1, 5.2), {6.1: 6.2}, my_seventh, my_eight, my_eight())
my_list = [1, 2, 3, 4, 5]
def first_level():
def second_level():
debug(my_list[:2],
my_list[3:])
second_level()
first_level()
Output when running this code is:
Code context: debug(a, b, c, b+2)
Actual arguments: (0.2, 1.2, 1.2, 3.2)
Code context: debug([4.1, 4.2], (5.1, 5.2), {6.1: 6.2}, my_seventh, my_eight, my_eight())
Actual arguments: ([4.1, 4.2], (5.1, 5.2), {6.1: 6.2}, <function my_seventh at 0x102294488>, <function my_seventh at 0x102294488>, 7)
Code context: my_list[3:])
Actual arguments: ([1, 2], [4, 5])
In other words, using the inspect options to get the frameinfo will give you the source line (or last line thereof) which triggered your function call. However if the actual call is split over multiple lines, only the last line is given as code context. And so far I've not found a way to connect the named variables in the code context to the actual arguments.