【问题标题】:How to use inspect to get the caller's info from callee in Python?如何使用inspect从Python中的被调用者那里获取调用者的信息?
【发布时间】:2011-04-12 06:57:26
【问题描述】:

我需要从被调用者那里获取调用者信息(什么文件/什么行)。我了解到我可以为此目的使用 inpect 模块,但不完全是。

如何通过检查获取这些信息?或者有没有其他方法可以获取信息?

import inspect

print __file__
c=inspect.currentframe()
print c.f_lineno

def hello():
    print inspect.stack
    ?? what file called me in what line?

hello()

【问题讨论】:

    标签: python inspect


    【解决方案1】:

    调用者的帧比当前帧高一帧。您可以使用inspect.currentframe().f_back 来查找调用者的框架。 然后使用inspect.getframeinfo获取调用者的文件名和行号。

    import inspect
    
    def hello():
        previous_frame = inspect.currentframe().f_back
        (filename, line_number, 
         function_name, lines, index) = inspect.getframeinfo(previous_frame)
        return (filename, line_number, function_name, lines, index)
    
    print(hello())
    
    # ('/home/unutbu/pybin/test.py', 10, '<module>', ['hello()\n'], 0)
    

    【讨论】:

    • @prosseek:要获取调用者的调用者,只需将索引[1] 更改为[2]。 (inspect.getouterframes 返回帧列表...)。 Python 组织精美。
    • 你也可以使用inspect.currentframe().f_back。
    • 这似乎没有提供获取文件名完整路径的方法。
    • @JasonS:“堆栈帧中的文件名是应用程序的relative to the start up directory”。
    • 此代码示例有效,但性能很差。如果您只对单个帧而不是整个堆栈跟踪感兴趣,您可以获取前一帧并检查它的帧信息:filename, line_number, clsname, lines, index = inspect.getframeinfo(sys._getframe(1))
    【解决方案2】:

    我建议改用inspect.stack

    import inspect
    
    def hello():
        frame,filename,line_number,function_name,lines,index = inspect.stack()[1]
        print(frame,filename,line_number,function_name,lines,index)
    hello()
    

    【讨论】:

    • 按照@unutbu 的建议使用getouterframes 有什么好处?
    • 更紧凑,更能体现意图。
    • 请注意 getouterframes(currentframe())stack() 在底层是等效的 github.com/python/cpython/blob/master/Lib/inspect.py#L1442
    • 使用 stack() 的另一个好处是它展示了如何轻松获取其他帧。如果,例如。您的 hello() 函数首先被另一个函数调用,您可以更新它以返回两个级别。
    【解决方案3】:

    我发布了一个用于检查的包装器,它使用简单的堆栈帧寻址,通过单个参数 spos 覆盖堆栈帧:

    例如pysourceinfo.PySourceInfo.getCallerLinenumber(spos=1)

    spos=0 是库函数,spos=1 是调用者,spos=2 是调用者的调用者,等等。

    【讨论】:

      【解决方案4】:

      如果调用者是主文件,只需使用 sys.argv[0]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-18
        • 2012-08-01
        • 2011-10-01
        • 2010-10-25
        • 2012-12-17
        • 1970-01-01
        • 2020-08-18
        • 2017-01-25
        相关资源
        最近更新 更多