Python 3.7中使用exec()执行局部全局变量时出错的问题排查
问题分析与解决
你的代码报错的核心原因是exec的命名空间和函数局部变量作用域不匹配:
- 函数内的
df1、df2是局部变量,而你传给exec()的第二个参数是globals(),也就是模块级的全局命名空间,这个空间里没有df1、df2,所以执行exec时会抛出NameError,找不到这两个变量。 - 就算强行把变量放到全局,
exec生成的concat也会被存在全局空间,函数内的print(concat)依然会报错,因为函数局部作用域无法直接访问未声明的全局变量。
修正方案
推荐自己创建一个包含所需变量的命名空间字典,让exec在这个字典里执行代码,之后再从字典中取出生成的concat变量:
import pandas as pd def test_exec(): df1 = pd.DataFrame({"a":[1, 2, 3, 4], "b":[5, 6, 7, 8]}) df2 = pd.DataFrame({"a":[1, 2, 3], "b":[5, 6, 7]}) formula = "concat = pd.concat([df1,df2],ignore_index=True)" # 构造包含所需变量的命名空间 exec_ns = {"df1": df1, "df2": df2, "pd": pd} # 在指定命名空间内执行代码 exec(formula, exec_ns) # 从命名空间中获取生成的concat变量 concat = exec_ns["concat"] print(concat) test_exec()
补充说明
- 不要直接用
locals()作为exec的命名空间:在Python函数内部,locals()返回的字典是只读的(修改后不会同步到实际局部作用域),所以直接用exec(formula, locals())可能无法让函数内获取到concat变量。 - 这种手动管理命名空间的方式更安全,也避免了污染全局作用域。
内容的提问来源于stack exchange,提问作者Junior P
相关产品推荐
相关产品推荐

