如何获取Python呼叫者对象信息



如何从函数中获取呼叫者对象,并检查有关该调用者的信息?

class A(object):
    def class_A_fun(self):
            print 'caller from class'  # → B
            print 'caller from method'  # → class_B_fun
            print 'caller module'  # → foomodule
            print 'caller instance'  # → obj
            print 'caller object file name or path'  # → 'foomodule.py'
class B(object):
    def class_B_fun(self):    
        obj = A()
        obj.class_A_fun()        
if __name__ == "__main__":
    obj = B()
    obj.class_B_fun()
from inspect import currentframe, getframeinfo, getmodulename
from pathlib import Path

class A(object):
    def class_A_fun(self):
        cuurent_frame = currentframe()
        caller_frame = cuurent_frame.f_back
        filename, lineno, function, code_context, index = getframeinfo(caller_frame)
        # first_arg_name in this case is 'self', but could be sth else
        first_arg_name = caller_frame.f_code.co_varnames[0]
        # f_locals is the local namespace seen by the frame
        caller_instance = caller_frame.f_locals[first_arg_name]
        assert caller_instance is caller_frame.f_back.f_locals['b'] is b
        assert type(caller_instance).__name__ == 'B'
        assert function == caller_frame.f_code.co_name == 'class_B_fun'
        assert filename == caller_frame.f_code.co_filename == __file__
        assert getmodulename(filename) == Path(__file__).stem

class B(object):
    def class_B_fun(self):
        a = A()
        a.class_A_fun()

if __name__ == "__main__":
    b = B()
    b.class_B_fun()

并非所有这些都是可能的,但是大多数可以通过检查呼叫堆栈来获得:

import sys
import inspect
__metaclass__ = type
class Lorem:
    def ipsum(self):
        caller_frame = sys._getframe(1)
        caller_frameinfo = inspect.getframeinfo(caller_frame)
        print("Caller is in module {module!r}".format(
                module=inspect.getmodule(caller_frame)))
        print("Caller is defined in {path!r}, line {lineno}".format(
                path=inspect.getsourcefile(caller_frame),
                lineno=caller_frameinfo.lineno))
class Dolor:
    def sit_amet(self):
        lorem = Lorem()
        lorem.ipsum()

有关更多信息,请参见inspect模块的文档。

最新更新