Python Decorator for printing every line executed by a function
我想,为了调试目的,打印出与python方法中执行的每一行有关的内容。
例如,如果行中有一些赋值,我想打印为该变量赋值的值,如果有函数调用,我想打印出函数返回的值等。
所以,例如,如果我使用装饰器,应用于函数/方法,如:
1 2 3 4 5 6 | @some_decorator def testing() : a = 10 b = 20 c = a + b e = test_function() |
调用函数测试时,应打印以下内容:
1 2 3 4 | a = 10 b = 20 c = 30 e = some_value |
有没有办法实现这个目标?更基本的是,我想知道我是否可以编写一个可以逐行查看其他代码的代码,检查它是什么类型的指令,等等。或者就像我们可以得到一个字典来查找所有变量一个类,我可以得到像数据结构这样的字典来获取函数中的每个指令,这是一个好的元程序可以得到的。
因此,我特别期待使用装饰器的解决方案,因为我很好奇是否可以有一个装饰器可以逐行遍历整个功能,并逐行装饰,
但欢迎任何和所有解决方案。
提前致谢。
这样的事怎么样? 这对你有用吗?
调试上下文:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | import sys class debug_context(): """ Debug context to trace any function calls inside the context""" def __init__(self, name): self.name = name def __enter__(self): print('Entering Debug Decorated func') # Set the trace function to the trace_calls function # So all events are now traced sys.settrace(self.trace_calls) def __exit__(self, *args, **kwargs): # Stop tracing all events sys.settrace = None def trace_calls(self, frame, event, arg): # We want to only trace our call to the decorated function if event != 'call': return elif frame.f_code.co_name != self.name: return # return the trace function to use when you go into that # function call return self.trace_lines def trace_lines(self, frame, event, arg): # If you want to print local variables each line # keep the check for the event 'line' # If you want to print local variables only on return # check only for the 'return' event if event not in ['line', 'return']: return co = frame.f_code func_name = co.co_name line_no = frame.f_lineno filename = co.co_filename local_vars = frame.f_locals print (' {0} {1} {2} locals: {3}'.format(func_name, event, line_no, local_vars)) |
调试装饰器:
1 2 3 4 5 6 7 | def debug_decorator(func): """ Debug decorator to call the function within the debug context""" def decorated_func(*args, **kwargs): with debug_context(func.__name__): return_value = func(*args, **kwargs) return return_value return decorated_func |
用法
1 2 3 4 5 6 7 | @debug_decorator def testing() : a = 10 b = 20 c = a + b testing() |
产量
1 2 3 4 5 6 7 8 | ########################################################### #output: # Entering Debug Decorated func # testing line 44 locals: {} # testing line 45 locals: {'a': 10} # testing line 46 locals: {'a': 10, 'b': 20} # testing return 46 locals: {'a': 10, 'b': 20, 'c': 30} ########################################################### |