Python3.8函数内调用vars()引用全局变量触发KeyError,但变量实际存在
问题核心原因
vars()函数返回的是当前代码执行作用域对应的命名空间字典,并非固定指向模块全局作用域。
- 当代码运行在函数内部时,
vars()获取的是当前函数自己的局部作用域命名空间。此时执行vars()["ids1"],本质是在函数的局部变量集合中查找名为ids1的键,而这个键只存在于全局作用域中,因此触发KeyError。 - 你在交互解释器、模块顶层代码中直接调用
vars()["ids1"]能正常返回结果,是因为这些场景下的当前作用域本身就是全局模块层,vars()返回的就是全局变量表,自然可以匹配到提前定义的ids1。
可行的修正方式
- 把函数内的
vars()替换为globals():globals()会固定返回当前模块的全局命名空间字典,不受当前所在函数的作用域影响,修改后代码即可正常运行:def collect_id_sols(id_no): ids = globals()["ids" + str(id_no)] sols = globals()["sols" + str(id_no)] for line in range(0,len(ids)): # 原有无关逻辑保持不变 - 简洁替代写法:通过内置
getattr()读取模块全局属性,实现动态变量名的查找:import sys def collect_id_sols(id_no): module_obj = sys.modules[__name__] ids = getattr(module_obj, f"ids{id_no}") sols = getattr(module_obj, f"sols{id_no}") - 长期优化建议:不要零散定义带数字后缀的独立全局变量,将同类型变量整理为字典结构,比如预先定义
id_sols_map = {1: (ids1, sols1), 2: (ids2, sols2), ...},函数内直接通过id_no做键索引取值,既不需要动态拼接变量名,也能从根源上避免作用域查找的问题,代码可读性和可维护性更高。
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

