Why exec ("break") doesn't work inside a while loop

How the question arises, why does the code below not work:

while True: exec("break") 

I am doing the above in pycharm through the python 3.5.2 console. Initially, I thought it was a context issue, but after reading the documentation, I did not come closer to understanding why this error occurs.

 SyntaxError: 'break' outside loop 

Thanks in advance:)

EDIT: I understand that it works without exec (), by the way, I am curious why it will not work with exec (as circumstances require). Full answers are welcome.

+6
source share
5 answers

This is because exec() does not know your surrounding while loop. So the only expression that exec() sees in your example is break . Instead of using exec("break") just use break as is.

The only access to the exec() function has its surrounding area, these are the dictionaries globals() and locals() . The documentation for exec() gives some insight into how exec() works:

This function supports dynamic execution of Python code. the object must be either a string or a code object. If it is a string, the string is parsed as a set of Python statements, which is then executed (unless a syntax error occurs). [1] If it is a code object, it just executes. In all cases, it is expected that the executed code will be valid as an input file (see the "File Input" section of the Reference Guide). Keep in mind that return and yield statements cannot be used outside function definitions even in the context of code passed to exec (). The return value is None.

In all cases, if optional parts are omitted, the code is executed in the current area. If only global variables are provided, this should be a dictionary that will be used for both global and local variables. If global and local values ​​are specified, they are used for global and local variables, respectively. If provided, local residents can be any object of comparison. Remember that at the module level, global and local languages ​​are one and the same dictionary. If exec receives two separate objects in the form of global and local, the code will be executed as if it were embedded in the class definition.

If the global dictionary does not contain a value for the built-in key, a link to the built-in built-in modules dictionary is inserted under this key. This way, you can control which built-in functions are available for executable code by inserting your own built- in dictionary of globals before passing it to exec ().

+3
source

The exec statement executes a bit of code regardless of the rest of your code.

Hence the line:

 exec("break") 

tantamount to calling break from nowhere, in a script where nothing happens and where there is no loop.

The correct way to call the break statement:

 while True: break 

EDIT

A comment from Leaf made me think.

Actually, the exec statement does not run code from nowhere.

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

The best answer, as I understand it, is that exec executes a piece of code in the same environment as the source code, but independently of it.

This basically means that all variables that exist at the time exec are called can be used in code called exec . But the context is all new, so return , break , continue and other operators that need context will not work if the correct context is not created.

By the way, I kept the word "statement" when I talked about exec , but it became a function in Python3, just like print .

+2
source

exec() is a function. Assuming for simplicity that the function call is its own operator (as in your example), it can end in one of the following ways:

  • the function returns normally - in this case, the next statement is executed in accordance with the control flow;

  • an exception is thrown / called from the function - in this case the corresponding except clause is executed in the call stack (if any)

  • the entire program terminates due to an explicit call to exit () or the equivalent - there is nothing to execute.

Calling break (as well as return or yield ) from within exec() will change the program flow in a way that is incompatible with the described semantics of the function call.

Note that the documentation for exec() contains a special note about using return and yield inside exec()

Remember that return and yield cannot be used outside function definitions even in the context of code passed to exec() .

A similar restriction applies to the break statement (with the difference that it cannot be used outside of loops), and I wonder why it was not included in the documentation.

+2
source

exec is a built-in function

Python insists break should happen inside a loop, not inside a function

What happens in your code, you put a break inside a function that is exec , you cannot break out of a loop by doing break inside a function called inside a loop.

For ex

 >>> def func(): break SyntaxError: 'break' outside loop >>> 
+1
source

Try to split without exec ():

 while True: break 
0
source

Source: https://habr.com/ru/post/1012342/


All Articles