Python跨模块调用时如何获取传入参数对应的变量名
问题原因与解决方案
核心问题根因
Python内置的globals()函数返回的是函数定义所在模块的全局命名空间,而非函数调用方所在模块的全局命名空间。
你在tests.py中定义了A.prints方法,因此不管在哪里调用该方法,方法内部的globals()默认只会读取tests.py模块的全局变量。当你从main.py导入调用时,main.py中定义的s、id不在tests.py的全局命名空间内,自然匹配不到对应变量名,也就没有输出。
解决方法
方案1:主动传入调用方全局命名空间
修改tests.py的prints方法,新增参数接收调用方的全局命名空间,兼容原有调用逻辑:
class A(): # 新增caller_globals参数,默认取当前模块全局变量兼容原有逻辑 def prints(self, *f, caller_globals=None): use_globals = caller_globals if caller_globals is not None else globals() for j in f: for i in use_globals: if use_globals[i] == j: print(f'{i}={j}', end=' ') print() # 原有测试逻辑不变 s=3;id=2 # 运行main.py时该部分代码不会执行 a=A() a.prints(s,id)
调用时传入当前模块的globals()即可,修改后的main.py:
from tests import A if __name__ =='__main__': id=3 s=1 a=A() a.prints(s, id, caller_globals=globals())
方案2:自动获取调用方全局命名空间
如果不想修改调用逻辑,可以通过inspect模块自动获取调用方的全局命名空间,只需修改tests.py即可:
import inspect class A(): def prints(self,*f): # 读取调用栈上一层的全局命名空间 caller_globals = inspect.stack()[1][0].f_globals for j in f: for i in caller_globals: if caller_globals[i]==j: print(f'{i}={j}', end=' ') print() s=3;id=2 # 运行main.py时该部分代码不会执行 a=A() a.prints(s,id)
原有main.py无需任何修改,直接运行即可得到预期输出。
注意事项
如果同一个全局命名空间内有多个变量的值完全相同,匹配时会输出先遍历到的变量名,结果可能不符合预期。
内容的提问来源于stack exchange,提问作者Jr. dective
相关产品推荐
相关产品推荐

