8

我想获取有关 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可以吗?

4

3 回答 3

12

是的,该sys._getframe()函数让您从当前执行堆栈中检索帧,然后您可以使用inspect模块中的方法和文档进行检查;您将在属性中寻找特定的本地人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()函数生成带有附加信息的帧列表。

于 2012-08-03T16:07:50.003 回答
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>
于 2012-08-03T16:10:50.600 回答
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)
于 2014-01-29T20:36:46.930 回答