Tracing Functions in Python
Sometimes I want to debug the inputs and outputs of function calls to visualize flow or to follow execution passively.
Rather than adding logging statements and littering them around the code, a single decorator can be crafted to show the life cycle of a function:
def trace_args(f): def wrapper(*args): print "%s(%s)" % (f.__name__, ", ".join(str(arg) for arg in args)) ret = f(*args) print "%s(%s) => %s" % (f.__name__, ", ".join(str(arg) for arg in args), ret) return ret return wrapper
An example, given a function sum like the following:
def sum(a, b): return a + b >>> sum(1, 3) 4
Applying the decorator would look like this:
@trace_args def sum(a, b): return a + b >>> sum(1, 4) sum(1, 4) sum(1, 4) => 5 5
Slightly more complicated example:
@trace_args def sum(a, b): return a + b @trace_args def add_five(a): return sum(a, 5) >>> add_five(4) add_five(4) sum(4, 5) sum(4, 5) => 9 add_five(4) => 9 5
Use the following example to simply display the type of the input and outputs
def trace_args(f): def wrapper(*args): print "%s(%s)" % (f.__name__, ", ".join(str(type(arg)) for arg in args)) ret = f(*args) print "%s(%s) => %s" % (f.__name__, ", ".join(str(type(arg)) for arg in args), str(type(ret))) return ret return wrapper