2016-11-15 39 views
6

作为问题问,里面的工作为什么不下面的代码工作:为什么不执行exec(“突破”)while循环

while True: 
     exec("break") 

我通过Python 3.5执行上述pycharm。 2控制台。 我最初认为这是一个上下文问题,但在阅读文档后,我还没有接近理解为什么会出现此错误。

SyntaxError: 'break' outside loop 

感谢提前:)

编辑:我明白,这工作没有执行exec()顺便说一下,我很好奇,为什么它不会以exec工作(如需要我的情况它) - 全面的答案欢迎。没有EXEC

+0

'exec'是一个函数,'break'应该直接在循环中。 – user2728397

回答

3

这是因为exec()是无知的你周围while循环。因此,exec()在您的示例中看到的唯一声明是break。而不是使用exec("break"),只需按原样使用break即可。

唯一访问exec()函数有它的周围范围,是globals()locals()字典。 The documentation for exec()提供了exec()如何工作的一些见解:

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

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

如果全局变量字典不包含键builtin的值,则对该内置模块的内置字典的引用将插入到该键下。通过这种方式,您可以在将它传递给exec()之前,将自己的builtins字典插入到全局变量中,从而控制可执行代码可用的内建函数。

+0

所以这是一个上下文问题?有没有办法在当前命名空间/上下文中使用exec执行? – Sighonide

+0

@Sighonide据我所知,没有。 exec()只能访问全局变量,而不能访问语句。请问为什么你需要这个? –

+0

那是不幸的哈哈。我打算用它将字符串格式的命令传递给另一个进程,这将在该进程中操作循环和其他事物。 – Sighonide

0

尝试突破():

while True: 
    break 
+0

OP说他需要知道原因。你的回答没有解释它。 – user2728397

+0

@leaf嗯,我明白他不能评论,但这是一个非常低质量的答案。 – user2728397

2

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

因此,该行:

exec("break") 

,无异于叫break突然冒出来,在一个脚本,没有什么事情发生,并在不存在环路。

调用break说法正确的做法是:

while True: 
    break 

编辑

从叶的评论让我想想。

实际上,exec声明不会从无处运行代码。

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

一个更好的答案,因为据我所知,是exec运行在同一环境作为原代码的一段代码,而是独立于它。

这基本上意味着调用exec时刻存在的所有变量可用于由exec调用的代码。但上下文都是新的,所以return,break,continue和其他需要上下文的语句将不起作用,除非创建了正确的上下文。

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

+0

@leaf感谢您的思考;) –

+0

.....欢迎;) –

1

exec是一个内置的功能,

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

什么在你的代码的情况是你把break一个function里面是exec通过在循环内部调用的函数内执行 break,您无法摆脱循环。

对于防爆

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

exec()是一个函数。假设该函数调用构成其自身的陈述(就像在你的例子)简单,它可以通过以下方式之一结束:

  1. 功能正常返回 - 在这种情况下,根据下面的语句到控制流程执行;

  2. 引发异常/从功能抛出 - 在这种情况下,调用堆栈上匹配except条款(如果有的话)被执行

  3. 整个程序被终止,因为该显式调用退出( )或同等学历 - 没有什么可执行的。

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

注意the documentation on exec()包含在里面exec()使用returnyield特别说明:

请注意,returnyield陈述可能不外部函数定义 甚至代码的上下文中使用传递给 exec()函数。

类似的限制适用于break声明(与它可能不被外部循环被使用的比较),我不知道为什么它没有被列入的文件中。

+0

是的,'break'也应该直接在循环中,而不是像'exec'这样的函数内部。 – user2728397