Get function callers' information in python

牧云@^-^@ 提交于 2019-12-18 15:51:35

问题


I want to get information about the callers of a specific function in python. For example:

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."

Is it possible with python?


回答1:


Yes, the sys._getframe() function let's you retrieve frames from the current execution stack, which you can then inspect with the methods and documentation found in the inspect module; you'll be looking for specific locals in the f_locals attribute, as well as for the f_code information:

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__)

Note that you'll need to take some care to detect what kind of information you find in each frame.

sys._getframe() returns a frame object, you can chain through the whole stack by following the f_back reference on each. Or you can use the inspect.stack() function to produce a lists of frames with additional information.




回答2:


An example:

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)

Will retrieve the "immediate" caller.

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

And if wasn't called from another you get (in IDLE):

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



回答3:


Thanks to Jon Clements answer I was able to make a function that returns an ordered list of all callers:

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

and when called in a chain:

def f2():
    return f1()

def f3():
    return f2()

def f4():
    return f3()

print f4()

looks like this:

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

In my case I filter out anything at '<module>' and after, and then take the last item to be the name of the originating caller.

Or modify the original loop to bail at the first appearance of any name starting with '<':

frame = frame.f_back
name = frame.f_code.co_name
if name[0] == '<':
    break
names.append(name)


来源:https://stackoverflow.com/questions/11799290/get-function-callers-information-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!