Python - 获取上级调用者及相关变量信息

在比较复杂的项目中,可能希望获取上级调用者的信息,举个例子:

  1. 编写了一个处理器(Handler)对象,有一个 move() 成员函数
  2. 编写了一个任务(Task)对象,任务(Task)以通过处理器(Handler)完成一些工作
  3. 处理器(Handler)完成工作时,希望获取任务(Task)的一些信息

这时可以用 Python 提供的 inspect 模块完成相关的任务,你可以获取函数名、类名、局部变量、全局变量等各类信息

模块功能介绍

import inspect

inspect.stack() # 返回一个列表,其中每个元素都是一个命名元组(namedtuple),表示堆栈帧的信息
stack_current = inspect.stack()[0] # 当前运行的函数、环境等相关信息
stack_parent = inspect.stack()[1] # 上一级调用者的函数、环境等相关信息


# 以当前运行函数为例,说明成员信息;上级调用者也一样
stack_current.frame # 当前堆栈帧的帧对象。详细解释见下
stack_current.filename # 当前堆栈帧的源文件名称
stack_current.lineno # 当前堆栈帧的源代码行号
stack_current.name # 当前堆栈帧中函数的名称(如果适用)
stack_current.line # 当前堆栈帧的源代码行(如果可用)


# 接下来介绍 frame 对象
stack_current.frame.f_locals # 当前的所有局域内变量,dict
stack_current.frame.f_globals # 全局变量
stack_current.frame.f_builtins # 内置字典

当然 inspect 模块的功能不至于获取调用者信息,也可以深入了解一个对象、一个函数的定义等等。但不在今日的篇幅展开,感兴趣的可以直接查阅 Python 的 官方文档,链接 3.12 的文档。

举个例子

以我文章最初提到的 Handler 和 Task 的例子做个说明:

import inspect

# 定义处理器
class Handler():

	def __init__(self):
		pass
	
	def move(self, direction, step=1):
		stack_parent = inspect.stack()[1] # 获取上级调用者
		f_locals_for_stack_parent = stack_parent.frame.f_locals # 获取上级调用者的局部变量
		task_name = f_locals_for_stack_parent['self'].name # 获取上级调用者 self 变量的 name 成员
 
		print(f'{task_name}: moved {direction} {step} times')

# 定义任务
class Task():
	
	def __init__(self, name, handler):
		self.name = name
		self.handler = handler
	
	def run(self):
		self.handler.move('left', step=5)
		self.handler.move('right', step=2)

# 开始任务
map_handler = Handler()
go_home_task = Task(name='go home', handler=map_handler)
go_home_task.run()

输出结果:

go home: moved left 5 times
go home: moved right 2 times

常见任务

# 获取模块名称
inspect.stack()[n].frame.f_globals['__name__']

# 获取函数名称
inspect.stack()[n].frame.f_locals['__name__']

# 获取调用函数的对象
inspect.stack()[n].frame.f_locals['self']
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值