在python中获取函数调用者的信息

问题描述 投票:8回答:3

我想获得有关python中特定函数的调用者的信息。例如:

class SomeClass():
    def __init__(self, x):
        self.x = x
    def caller(self):
        return special_func(self.x)

def special_func(x):
    print "My caller is the 'caller' function in an 'SomeClass' class."

有可能与python?

python introspection callstack
3个回答
11
投票

是的,sys._getframe()函数允许您从当前执行堆栈中检索帧,然后您可以使用inspect module中的方法和文档进行检查;您将在f_locals属性以及f_code信息中查找特定的本地人:

import sys
def special_func(x):
    callingframe = sys._getframe(1)
    print 'My caller is the %r function in a %r class' % (
        callingframe.f_code.co_name, 
        callingframe.f_locals['self'].__class__.__name__)

请注意,您需要注意检测每个帧中找到的信息类型。

sys._getframe()返回一个框架对象,您可以通过遵循每个框架上的f_back引用来链接整个堆栈。或者您可以使用inspect.stack() function生成包含附加信息的帧列表。


3
投票

一个例子:

def f1(a):
    import inspect
    print 'I am f1 and was called by', inspect.currentframe().f_back.f_code.co_name
    return a

def f2(a):
    return f1(a)

将检索“立即”调用者。

>>> f2(1)
I am f1 and was called by f2

如果没有从另一个调用,你得到(在IDLE中):

>>> f1(1)
I am f1 and was called by <module>

2
投票

感谢Jon Clements的回答,我能够创建一个返回所有调用者的有序列表的函数:

def f1():
    names = []
    frame = inspect.currentframe()
    ## Keep moving to next outer frame
    while True:
        try:
            frame = frame.f_back
            name = frame.f_code.co_name
            names.append(name)
        except:
            break
    return names

当在链中调用时:

def f2():
    return f1()

def f3():
    return f2()

def f4():
    return f3()

print f4()

看起来像这样:

['f2', 'f3', 'f4', '<module>']

在我的情况下,我在'<module>'和之后筛选出任何内容,然后将最后一项作为原始调用者的名称。

或者在'<'开头的任何名字的第一次出现时修改原始循环以保释:

frame = frame.f_back
name = frame.f_code.co_name
if name[0] == '<':
    break
names.append(name)
© www.soinside.com 2019 - 2024. All rights reserved.