繁体   English   中英

为什么exec(“break”)不在while循环中工作

[英]Why doesn't exec(“break”) work inside a while loop

正如问题所问,为什么以下代码不起作用:

while True:
      exec("break")

我通过python 3.5.2控制台在pycharm中执行上面的操作。 我最初认为这是一个上下文问题,但在阅读文档之后,我还没有接近理解为什么会发生这种错误。

SyntaxError: 'break' outside loop

提前致谢 :)

编辑:我知道它的工作没有exec()顺便说一句,我很好奇为什么它不能与exec一起工作(因为我的情况需要它) - 全面的答案欢迎。

这是因为exec()对你周围的循环无知。 因此, exec()在您的示例中看到的唯一语句是break 而不是使用exec("break") ,只需使用break

exec()函数对其周围范围的唯一访问是globals()locals()字典。 exec()的文档提供了一些有关exec()如何工作的见解:

此函数支持Python代码的动态执行。 object必须是字符串或代码对象。 如果它是一个字符串,则将该字符串解析为一组Python语句,然后执行该语句(除非发生语法错误)。 [1]如果是代码对象,则只执行它。 在所有情况下,执行的代码应该作为文件输入有效(请参见“参考手册”中的“文件输入”部分)。 请注意,即使在传递给exec()函数的代码的上下文中,也不能在函数定义之外使用return和yield语句。 返回值为None。

在所有情况下,如果省略可选部分,则代码在当前范围内执行。 如果只提供全局变量,则它必须是字典,它将用于全局变量和局部变量。 如果给出全局变量和局部变量,则它们分别用于全局变量和局部变量。 如果提供,则locals可以是任何映射对象。 请记住,在模块级别,全局变量和本地变量是相同的字典。 如果exec获得两个单独的对象作为全局变量和局部变量,则代码将被执行,就像它嵌入在类定义中一样。

如果全局字典不包含键内置函数的值,则在该键下插入对内置模块内置字典的引用。 这样,通过将自己的内置字典插入到globals中,然后将其传递给exec(),就可以控制执行代码可用的内置函数。

exec语句独立于代码的其余部分运行一些代码。

因此,该行:

exec("break")

等于在一个没有其他任何事情的脚本中调用break冒出的地方,并且没有循环存在。

调用break语句的正确方法是:

while True:
    break

编辑

Leaf的评论让我思考它。

实际上, exec语句不会无处运行代码。

>>> i = 12
>>> exec("print(i)")
12

据我所知,一个更好的答案是exec在与原始代码相同的环境中运行一段代码,但独立于它。

这基本上意味着,所有存在此刻的变量exec被称为可以通过调用的代码中使用exec 但是上下文都是新的,所以returnbreakcontinue和其他需要上下文的语句都不会起作用,除非创建了正确的上下文。

顺便说一下,在谈论exec时我保留了“声明”这个词,但它已经成为Python3中的一个函数,就像print一样。

exec()是一个函数。 假设为简单起见,函数调用构成了自​​己的语句(就像在您的示例中一样),它可能以下列方式之一结束:

  1. 函数正常返回 - 在这种情况下,执行根据控制流的下一个语句;

  2. 从函数引发/抛出异常 - 在这种情况下,执行调用堆栈上的匹配except子句(如果有)

  3. 由于显式调用exit()或等效函数,整个程序终止 - 没有任何东西可以执行。

exec()内部调用break (以及returnyield )将以与函数调用语义的描述方面不兼容的方式修改程序执行流。

请注意, 在文件exec()包含对使用的特殊说明, returnyield内部exec()

请注意,即使在传递给exec()函数的代码的上下文中,也不能在函数定义之外使用returnyield语句。

类似的限制适用于break语句(区别在于它可能不在循环外使用),我想知道为什么它没有包含在文档中。

exec是内置函数,

Python坚持认为break应该在循环内部发生,而不是在function内部发生

什么在你的代码的情况是你把break一个内部functionexec你无法通过执行跳出循环的break一这就是所谓的内循环功能内。

对于Ex

>>> def func():
        break
SyntaxError: 'break' outside loop
>>> 

尝试在没有exec()的情况下休息:

while True:
  break

exec函数在代码中运行代码,这意味着它无处不在! 所以,你的while循环没有抓住它。 您的文件是<stdin> exec在另一个名为<string>文件上运行。 它无法识别它在哪里试图打破没有循环的循环。 所以,你的代码是这样的:

while True:
    exec("break")

它应该是这样的:

while True:
    break

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM