Python3模块导入后如何正确列出父模块的用户自定义变量
问题原因
globals()默认返回的是函数定义所在模块的全局命名空间,所以把函数放到单独模块后,读到的永远是定义这个函数的模块里的变量。
之前尝试的import __main__读取__main__.__dict__的方案,只有当调用函数的脚本是程序直接启动的入口脚本时才生效——如果导入工具函数的模块本身不是顶层入口,__main__指向的是最顶层启动的那个脚本,自然读不到目标模块的变量。
可行实现
用Python标准库inspect获取调用方的栈帧,直接从栈帧中读取调用者的全局命名空间即可,不受函数定义位置、模块导入层级影响:
import inspect def list_defined_vars(): # 取当前函数的上一级调用栈帧 caller_frame = inspect.currentframe().f_back # 读取调用方的全局变量字典 caller_globals = caller_frame.f_globals for var_name, var_value in caller_globals.items(): # 过滤掉Python内置的双下划线特殊变量 if var_name.startswith('__'): continue var_type = type(var_value) print(f"{var_name} is {var_type} and is equal to {var_value}")
可选优化
如果需要过滤掉导入的模块、内置函数这类非用户手动定义的内容,可以加一层类型判断:
import inspect import types def list_defined_vars(): caller_frame = inspect.currentframe().f_back caller_globals = caller_frame.f_globals for var_name, var_value in caller_globals.items(): if var_name.startswith('__'): continue # 过滤导入的模块、内置函数/方法 if isinstance(var_value, (types.ModuleType, types.BuiltinFunctionType, types.BuiltinMethodType)): continue var_type = type(var_value) print(f"{var_name} is {var_type} and is equal to {var_value}")
提示:栈帧读取完成后如果需要长期持有变量,建议手动释放
caller_frame引用避免循环引用,日常单次调用不需要额外处理也不会有问题。
内容的提问来源于stack exchange,提问作者TheCrazySwede
相关产品推荐
相关产品推荐

