当前位置: 首页 > 面试题库 >

Python Decorator用于打印函数执行的每一行

端木弘方
2023-03-14
问题内容

我想出于调试目的,打印出与python方法中执行的每一行有关的内容。

例如,如果该行中有一些赋值,我想打印为该变量分配的值,如果有一个函数调用,我想打印出该函数返回的值,等等。

因此,例如,如果我要使用装饰器,则将其应用于函数/方法,例如:

@some_decorator
def testing() : 
    a = 10
    b = 20
    c = a + b
    e = test_function()

调用功能测试时,应打印以下内容:

a = 10
b = 20  
c = 30
e = some_value

有什么办法可以做到这一点?更重要的是,我想知道我是否可以编写可以逐行通过其他代码的代码,检查它是哪种类型的指令,等等。或者也许像我们可以找到一个字典来找出其中的所有变量一个类,我能否得到像数据结构这样的字典来获取函数中的每条指令,这是元程序所能获得的。

因此,我特别在寻找使用装饰器的解决方案,因为我很好奇是否有一个装饰器可以逐行遍历整个功能,并逐行装饰它,但是任何一种解决方案都是受欢迎的。

提前致谢。


问题答案:

这样的事情怎么样?这对您有用吗?

调试上下文:

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))

调试装饰器:

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

用法

@debug_decorator
def testing() : 
    a = 10
    b = 20
    c = a + b

testing()

输出量

###########################################################
#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}
###########################################################


 类似资料:
  • 问题内容: 该程序输出- 它不应该提供输出- 因为首先ai应该打印1,然后执行a.getI()并应该打印A 2 问题答案: 在此表达式中: 首先评估对的调用,然后通过连接加号形成字符串

  • 问题内容: 我知道这将在实际执行之前执行脚本打印每一行。如何使Perl和Python解释器执行相同的操作? 问题答案: Devel :: Trace是Perl的类似物,trace模块是Python的。

  • 问题内容: 我刚开始学习Python,目前正在读一本教我的书,在这本书中,一个函数与我在下面编写的函数一样,会打印第一个函数中定义的实际文本。我运行我的脚本说: 作为输出。我究竟做错了什么?我安装了错误的Python或其他东西吗?我下载了3.3.0版本 这是我的代码: 问题答案: 您的函数已经打印了文本,您不需要打印函数。只是称呼他们(别忘了括号)。

  • 现在我把所有结果都放在一行了。如何在这个Java流中创建逻辑8,将forEach循环中的每5个字放入换行符()。每六个字印一行。

  • #include <stdio.h> #include <pthread.h> typedef struct { int a; int b; int c; int d; pthread_mutex_t mutex; }ex_st; int main(void) { ex_st st = {1, 2,

  • 本文向大家介绍将函数应用于Python中Pandas DataFrame中的每一行,包括了将函数应用于Python中Pandas DataFrame中的每一行的使用技巧和注意事项,需要的朋友参考一下 在本教程中,我们将学习列表的最常用方法,即append()和extend()。让我们一一看。 应用() 它用于将函数应用于DataFrame的每一行。例如,如果我们想将每个中的所有数字相乘并将其添加为