Python中exec动态定义变量后显式调用报错问题求助
问题原因及解决办法
你遇到的问题核心在于Python函数的变量解析机制:
- 函数在编译成字节码时,会扫描所有变量名,把
print(bbb)里的bbb标记为局部变量,运行时会直接从函数的局部变量栈中查找,而非从locals()字典里取值。 exec()是在运行时把变量添加到locals()字典,但这个操作不会同步到函数的局部变量栈,所以直接写print(bbb)时,Python找不到对应变量,抛出NameError。- 断点手动执行时,是在Spyder的交互式调试环境中,此时会直接从
locals()字典里查找变量,因此能正常访问。
解决办法
1. 改用字典存储(推荐方案)
完全避免动态创建变量,用字典管理动态生成的值,代码更清晰、安全:
def function_(input_dict): dynamic_vars = {} var_name = input_dict['aaa'] dynamic_vars[var_name] = 5 print(var_name in dynamic_vars) # Prints True print(dynamic_vars[var_name]) # 直接通过字典访问 input_dict = {'aaa': 'bbb'} function_(input_dict)
2. 从locals()中显式获取变量
既然exec()把变量加到了locals()字典,就直接从里面取值:
def function_(input_dict): string = input_dict['aaa'] + " = 5" exec(string) var_name = input_dict['aaa'] print(var_name in locals()) # Prints True print(locals()[var_name]) # 从locals字典中取出变量 input_dict = {'aaa': 'bbb'} function_(input_dict)
3. 用globals()替代局部作用域(不推荐,易污染全局命名空间)
如果一定要直接用变量名访问,可以把变量创建到全局作用域,这样编译阶段不会把它标记为局部变量:
def function_(input_dict): string = input_dict['aaa'] + " = 5" exec(string, globals()) # 指定globals作为exec的命名空间 var_name = input_dict['aaa'] print(var_name in globals()) # Prints True print(bbb) # 现在可以直接访问 input_dict = {'aaa': 'bbb'} function_(input_dict)
内容的提问来源于stack exchange,提问作者Nicolas
相关产品推荐
相关产品推荐

