Python 如何保持堆栈上每个调用函数的调用计数(检测循环)?

Python 如何保持堆栈上每个调用函数的调用计数(检测循环)?,python,python-3.x,logging,stack,Python,Python 3.x,Logging,Stack,我想编写一个自定义日志/调试函数,其中包括提供有关调用堆栈的信息。很有可能检查堆栈并找到导致当前日志函数调用的所有调用。下面的示例可能不是最好的方法(使用inspect模块),但它可以工作 import inspect def log(value): funcs = [value] frame = inspect.currentframe() while frame: funcs.append(f"({frame.f_code.co_name

我想编写一个自定义日志/调试函数,其中包括提供有关调用堆栈的信息。很有可能检查堆栈并找到导致当前日志函数调用的所有调用。下面的示例可能不是最好的方法(使用inspect模块),但它可以工作

import inspect


def log(value):
    funcs = [value]
    frame = inspect.currentframe()
    while frame:
        funcs.append(f"({frame.f_code.co_name})")
        frame = frame.f_back
    print(" ".join(reversed(funcs)))


def bar1():
    log("logging from bar1")


def foo1():
    for i in range(2):
        bar1()


def bar2():
    for i in range(2):
        log("logging from bar2")


def foo2():
    bar2()


def main():
    foo1()
    print("****")
    foo2()


if __name__ == '__main__':
    main()
(<module> 8741717982340) (main 8741717938436) (foo1 8741717949348) (bar1 8741717938529) (log 8741717874238) logging from bar1
(<module> 8741717982340) (main 8741717938436) (foo1 8741717949348) (bar1 8741717921765) (log 8741717874267) logging from bar1
****
(<module> 8741717982340) (main 8741717938436) (foo2 8741717921565) (bar2 8741717913222) (log 8741717874296) logging from bar2
(<module> 8741717982340) (main 8741717938436) (foo2 8741717921565) (bar2 8741717913222) (log 8741717874325) logging from bar2
是否有一种方法可以记录自父调用以来的每个调用的计数(基本上用于检测循环)?

为了澄清这一点,回顾前面的示例,解决方案应该能够产生类似于此的输出

(<module>) (main 0) (foo1 0) (bar1 0) (log 0) logging from bar1
(<module>) (main 0) (foo1 0) (bar1 1) (log 0) logging from bar1
****
(<module>) (main 0) (foo2 0) (bar2 0) (log 0) logging from bar2
(<module>) (main 0) (foo2 0) (bar2 0) (log 1) logging from bar2
如果你运行它,你会得到这样的结果

(<module> 8757045858692) (main 8757045814788) (foo1 8757045825700) (bar1 8757045814881) (log 8757045750590) logging from bar1
(<module> 8757045858692) (main 8757045814788) (foo1 8757045825700) (bar1 8757045814881) (log 8757045750590) logging from bar1
****
(<module> 8757045858692) (main 8757045814788) (foo2 8757045798117) (bar2 8757045789574) (log 8757045750590) logging from bar2
(<module> 8757045858692) (main 8757045814788) (foo2 8757045798117) (bar2 8757045789574) (log 8757045750590) logging from bar2
(<module> 8757045858692) (main 8757045814788) (foo1 8757045825700) (bar1 8757045814881) (log 8757045750590) logging from bar1
(<module> 8757045858692) (main 8757045814788) (foo1 8757045825700) (bar1 8757045814881) (log 8757045750590) logging from bar1
****
(<module> 8757045858692) (main 8757045814788) (foo2 8757045798117) (bar2 8757045789574) (log 8757045750590) logging from bar2
(<module> 8757045858692) (main 8757045814788) (foo2 8757045798117) (bar2 8757045789574) (log 8757045750590) logging from bar2
(<module> 8741717982340) (main 8741717938436) (foo1 8741717949348) (bar1 8741717938529) (log 8741717874238) logging from bar1
(<module> 8741717982340) (main 8741717938436) (foo1 8741717949348) (bar1 8741717921765) (log 8741717874267) logging from bar1
****
(<module> 8741717982340) (main 8741717938436) (foo2 8741717921565) (bar2 8741717913222) (log 8741717874296) logging from bar2
(<module> 8741717982340) (main 8741717938436) (foo2 8741717921565) (bar2 8741717913222) (log 8741717874325) logging from bar2