【问题标题】:How to get python caller object information?如何获取python调用者对象信息?
【发布时间】:2012-10-21 12:10:30
【问题描述】:

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

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

【问题讨论】:

  • 也许this 有帮助。 Google 'python get caller' 出现了一些不错的结果。
  • 你想做什么?这样做通常不是一个好主意。
  • @phant0m 我正在尝试开发自定义记录器框架,它可以获取如上所示的对象信息。

标签: python introspection


【解决方案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()

有关详细信息,请参阅documentation for the inspect module

【讨论】:

  • 调用者class呢?
【解决方案2】:
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()

【讨论】:

    猜你喜欢
    • 2012-08-01
    • 2011-04-12
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-31
    • 2020-04-19
    • 2014-12-03
    相关资源
    最近更新 更多