4

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

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()
4

2 回答 2

1

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

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

于 2015-07-01T08:05:20.233 回答
1
from inspect import currentframe, getframeinfo, getmodulename


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)

        # f_locals is the local namespace seen by the frame
        caller_instance = caller_frame.f_locals['self']
        print(f'caller instance: {caller_instance}')  # → obj
        print(f'caller from class: {type(caller_instance).__name__}')  # → B

        print(f'caller from method: {function}')  # → class_B_fun
        # alternatively:
        code = caller_frame.f_code
        assert function == code.co_name

        print(f'caller object file name or path: {filename}')  # → 'foomodule.py'
        # alternatively:
        assert filename == code.co_filename

        module_name = getmodulename(filename)
        print(f'caller module: {module_name}')  # → foomodule


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


if __name__ == "__main__":
    obj = B()
    obj.class_B_fun()
于 2021-08-16T08:44:13.747 回答