首页 > 编程问答 >exec 在函数和生成器中

exec 在函数和生成器中

时间:2024-09-24 20:41:08浏览次数:1  
标签:python generator exec

我需要在 python 中编写一个自定义 exec 函数(出于多种目的,但这不是这里的问题,所以这个名为 myExec 的自定义 exec 的功能将与现在的 exec 完全一样)。

我进入了这个问题:

def myExec(code):
    exec(code)

code = """
a = 1
print(a)
u = [a for x in range(3)]
print(u)
"""

myExec(code)

运行这个程序给出

1
Traceback (most recent call last):
  File "___.py", line 12, in <module>
    myExec(code)
  File "___.py", line 2, in myExec
    exec(code, globals(), locals())
  File "<string>", line 4, in <module>
  File "<string>", line 4, in <listcomp>
NameError: name 'a' is not defined

所以 print(a) 没有任何问题。但错误发生在 u = [a for x in range(3)] 行上。当生成器对象转换为列表时,名称 a 似乎未定义。

请注意,如果该行是 u = [a, a, a] ,则不会引发错误。如果我们使用 exec 而不是 myExec

任何原因以及如何解决这个问题?


出现此问题的原因是,列表推导式(list comprehensions)的作用域规则与 Python 中的其他代码块略有不同。在你的情况下,列表推导式 [a for x in range(3)] myExec 函数的 exec 调用中被执行,而不是在 myExec 函数的顶层执行。

exec 函数被调用时,它会创建一个新的作用域。列表推导式内的代码在这个新的作用域中执行,而不是在定义列表推导式的作用域中执行。因此,列表推导式无法访问在 exec 函数创建的作用域之外定义的变量。

为了解决这个问题,你可以将 locals() globals() 传递给 exec 函数,以便它可以在当前作用域中执行代码:

def myExec(code):
  exec(code, globals(), locals())

code = """
a = 1
print(a)
u = [a for x in range(3)]
print(u)
"""

myExec(code)

这样,列表推导式就能够访问在 myExec 函数中定义的 a 变量了。

需要注意的是 ,直接使用 exec eval 函数处理来自不受信任来源的代码可能会带来安全风险。如果你的代码需要处理不受信任的输入,请考虑使用更安全的替代方案,例如:

  • 使用 ast.literal_eval 来解析简单的 Python 字面量。
  • 使用沙箱环境,例如 RestrictedPython 来限制代码可以执行的操作。

标签:python,generator,exec
From: 79018528

相关文章

  • Python实现图形学光照和着色的Gouraud着色算法
    目录使用Python实现图形学光照和着色的Gouraud着色算法引言1.Gouraud着色算法概述1.1算法原理2.Python实现Gouraud着色算法2.1向量类2.2光源类2.3材质类2.4Gouraud着色器类2.5使用示例3.实例分析4.Gouraud着色算法的优缺点4.1优点4.2缺点5.改进方向6.应......
  • Python实现Phong着色模型算法
    目录使用Python实现Phong着色模型算法引言Phong着色模型的基本原理1.模型组成2.公式Phong着色模型的Python实现1.向量类的实现2.光源类的实现3.材质类的实现4.Phong着色器类的实现整体实现总结使用Python实现Phong着色模型算法引言在计算机图形学中,光照和......
  • 头歌实践教学平台 Python程序设计实训答案(二)
    第四阶段组合数据类型实验一列表的基本操作第1关:列表增删改:客人名单的变化任务描述列表是由按一定顺序排列的元素组成,其中的元素根据需要可能会发生变化。其中,列表元素的添加、删除或修改等是最常见的操作。下面以一则请客的故事来说明列表元素操作的应用场景。有个人邀......
  • 1、A+B(python语法格式,模块,主模块等)
    总结:python有许多模块,通过import引入模块,或者使用from从模块导入函数#导入math模块importmath#使用模块中的定义的变量或者函数的语法格式为:模块.变量/函数print(math.sqrt(25))#使用math模块中的sqrt函数,表示开平方根#从math模块中导入sqrtfrommathimpor......
  • 【Python学习笔记】字符串
    目录1.定义字符串2.基本操作2.1索引:2.2访问单个字符:2.3访问范围内字符:2.4单个字符编码3.转义符4.运算符5.格式化6.常用字符串函数6.1查找类函数6.2分割类函数6.3字符串连接方法6.4大小写字符转换方法6.5替换方法6.6删除字符串两端、右端或左端连续空白字符......
  • vscode 远程 切换python 虚拟环境
    在VSCode中远程切换Python虚拟环境是一个涉及多个步骤的过程,包括安装必要的扩展、连接到远程服务器、创建或激活虚拟环境,并在VSCode中选择相应的Python解释器。以下是一个详细的步骤指南,包括代码示例,旨在帮助我们完成这一过程。1.Vscode远程切换Python虚拟环境的步骤1.1步骤1:......
  • 常见算法——自相关的含义及Python、C实现
    常见算法——自相关的含义及C实现一、概念1.自相关概念2.滞后期示例说明:二、自相关的计算步骤:1.确定滞后期(Lag):2.计算平均值:3.计算自相关:三、示例Python自相关计算1.代码2.运行结果四、C语言实现自相关算法1.代码2.运行结果:3.优化4.检测规律波动一、概念1.自相关......
  • python中多维数组的cumsum的逆
    我想知道如何在Python中对多维数组进行累积和的逆运算。例如,我们可以通过PMy获得给定二维数组的累积数组T问题是,我如何从importnumpyasnpT=np.array([[1,3,2],[5,5,6],[1,8,3]])P=np.cumsum(np.cumsum(T,axis=0),axis=1)print(P)#Pisthe......
  • Vscode 远程切换Python虚拟环境
    在VSCode中远程切换Python虚拟环境是一个涉及多个步骤的过程,包括安装必要的扩展、连接到远程服务器、创建或激活虚拟环境,并在VSCode中选择相应的Python解释器。以下是一个详细的步骤指南,包括代码示例,旨在帮助我们完成这一过程。1.Vscode远程切换Python虚拟环境的步骤1.1步骤1......
  • 我无法在我的项目 Pycharm 中导入 opencv-python
    (myvenv)PSE:\Python>pipinstallopencv-pythonCollectingopencv-pythonUsingcachedopencv-python-4.10.0.84.tar.gz(95.1MB)Installingbuilddependencies...errorerror:subprocess-exited-with-error×pipsubprocesstoinstallbuilddepe......