Python内置函数exec如何传入传出值、不使用全局作用域并显式控制其作用域
完全显式控制exec作用域的实现方案
Python内置的exec函数原生支持自定义传入独立作用域,完全无需依赖真实的模块全局空间,只要正确传参即可实现零污染的变量注入与值提取。
核心原理
exec的完整函数签名为:
exec(source, globals=None, locals=None)
- 第一个参数为待执行的代码字符串
- 第二个参数是用户自定义的全局作用域字典,与当前模块的真实全局空间完全隔离
- 第三个参数是用户自定义的局部作用域字典
只要显式传入这两个字典,exec执行代码时的所有变量查找、变量绑定操作,都会完全在这两个字典的范围内完成,不会读写当前模块的真实全局作用域。
实现步骤
- 提前构建两个空字典作为独立的作用域容器,不关联任何外部真实作用域
- 将需要传递给exec执行代码的变量,显式写入对应的作用域字典
- 调用exec时,将两个作用域字典作为参数传入
- exec执行完成后,直接从对应的作用域字典中读取代码生成的输出值
适配原场景的可运行示例
针对你给出的代码逻辑,改造后的完全可控版本:
# 定义完全隔离的作用域字典,与真实全局空间无关联 exec_globals = {} exec_locals = {} # 显式注入exec需要的输入值 exec_globals['a'] = 100 exec_globals['b'] = 200 snip = ''' c = a + b d = c * 2 ''' # 显式把自定义作用域传给exec,替代默认的全局/局部作用域 exec(snip, exec_globals, exec_locals) # 从自定义字典中读取exec执行产生的结果 print(exec_globals['c']) # 输出 300 print(exec_locals['d']) # 输出 600
进阶权限控制技巧
如果需要实现更严格的沙箱级控制,可以在初始化全局作用域字典时手动指定允许访问的能力范围:
- 完全禁用所有内置函数:设置
exec_globals['__builtins__'] = {},此时exec执行的代码将无法调用print、int等任何内置能力 - 按需开放内置能力:手动将需要允许的内置对象加入字典,比如写入
exec_globals['print'] = print,让执行的代码可以使用受限的功能
常见注意事项
- 如果传入的globals和locals是同一个字典对象,代码内的所有变量绑定都会写入这个字典,取值逻辑会更简便
- 过往场景中出现的exec全局变量污染问题,本质都是调用exec时漏传了自定义作用域参数,导致exec默认复用了当前模块的真实全局/局部空间,只要显式传入自定义字典即可完全避免这类问题
内容的提问来源于stack exchange,提问作者Daniel Warfield
相关产品推荐
相关产品推荐

