Python 自动打印下一行变量以进行调试

Python 自动打印下一行变量以进行调试,python,debugging,logging,contextmanager,Python,Debugging,Logging,Contextmanager,调试复杂代码时,有时需要转换: def myfunction(self): ... self.foo.bar = self.baz.bla 进入 是否有一种方法(使用装饰器、上下文管理器或其他任何工具)自动打印变量名和下一行代码赋值的值(也可能是当前函数)? 例如: def myfunction(self): ... with debug: self.foo.bar = self.baz.bla 将输出: "myfunction self.f

调试复杂代码时,有时需要转换:

def myfunction(self):
    ...
    self.foo.bar = self.baz.bla
进入

是否有一种方法(使用装饰器、上下文管理器或其他任何工具)自动
打印
变量名和下一行代码赋值的值(也可能是当前函数)?

例如:

def myfunction(self):
    ...
    with debug:
        self.foo.bar = self.baz.bla
将输出:

 "myfunction self.foo.bar 123"

您可以使用inspect模块:

from inspect import currentframe

def f():
    a = 5
    debug_print("a")

def debug_print(var):
    locals = currentframe().f_back.f_locals
    print(f"{var} = {locals[var]}")

f()
另见此处:

我承认,这只是你要求的一部分,但也许是个好的开始

编辑:好的,这个怎么办:

from inspect import currentframe, getsourcelines

class A:
    def f(self):
        self.b = 5
        debug_print()
        self.a = A()
        self.a.a = 4
        debug_print()

    @staticmethod
    def g():
        A.c = 5
        debug_print()

def debug_print():
    frame = currentframe().f_back
    locals = frame.f_locals
    globals = frame.f_globals
    source, start = getsourcelines(currentframe().f_back.f_code)
    var_name = source[frame.f_lineno - 1 - start].split("=")[0]
    tokens = var_name.strip().split(".")
    var = locals.get(tokens[0], globals.get(tokens[0], None))
    for t in tokens[1:]:
        var = getattr(var, t)
    print(f"{var_name} = {var}")

a = A()
a.f()
a.g()

至少现在,它可以使用成员属性(包括
self
),甚至可以嵌套。还可以为类指定全局变量,例如静态属性。

谢谢!我希望能够做到这一点,而不必重写变量名。只需调试最后一行()
。这可能吗?很好的解决方案,谢谢!PS:它对类不起作用,例如
类测试:
def do(self):
self.blah=123
debug_print()
,但是
inspect
中肯定有什么东西可以做到这一点!好的,我们到了。当然,它还远没有普及。。。接下来您需要的是数组:
字段[2]=…
,但我想我把这个练习留给读者;-)
from inspect import currentframe, getsourcelines

class A:
    def f(self):
        self.b = 5
        debug_print()
        self.a = A()
        self.a.a = 4
        debug_print()

    @staticmethod
    def g():
        A.c = 5
        debug_print()

def debug_print():
    frame = currentframe().f_back
    locals = frame.f_locals
    globals = frame.f_globals
    source, start = getsourcelines(currentframe().f_back.f_code)
    var_name = source[frame.f_lineno - 1 - start].split("=")[0]
    tokens = var_name.strip().split(".")
    var = locals.get(tokens[0], globals.get(tokens[0], None))
    for t in tokens[1:]:
        var = getattr(var, t)
    print(f"{var_name} = {var}")

a = A()
a.f()
a.g()