如何从函数中获取呼叫者对象,并检查有关该调用者的信息?
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
模块的文档。