Este es un caso bastante interesante:
>>> def func():
... exec('print "hi from func"')
... def subfunction():
... return True
...
File "<stdin>", line 2
SyntaxError: unqualified exec is not allowed in function 'func' because
it contains a nested function with free variables
La razón por la que esto no funciona de hecho es que subfunction
contiene una variable libre, y dado que en Python 2, exec
teóricamente podría modificar la gente del lugar en el que contiene alcance, sería imposible decidir si la variable debería estar vinculada al alcance de la función global o principal. Uno de los versos en el Zen de Python es "En vista de la ambigüedad, rechace la tentación de adivinar". y esto es lo que hace Python 2.
Ahora la pregunta es: ¿qué es esta variable independiente? Bueno, es el True
!
De hecho, es reproducible con None
:
>>> def func():
... exec('print "hi from func"')
... def subfunction():
... return None
...
File "<stdin>", line 2
SyntaxError: unqualified exec is not allowed in function 'test2' because it contains a nested
function with free variables
Aunque None
no se pueden asignar a, y es considerado como un constante en el código de bytes, el analizador cochecito piensa que es una variable no unido aquí.
Pero si que se sustituya por 1
y funciona sin problemas:
>>> def test2():
... exec('print "hi from func"')
... def subfunction():
... return 1
...
>>>
Para evitar este error, explicitará las variables globales y posiblemente lugareños que van a ser utilizados por exec
, di:
>>> def test2():
... exec 'print "hi from test2"' in {}
... def subfunction():
... return None
...
>>>
En Python 3, exec
es simplemente una función simple y no es manejada especialmente por el analizador o el compilador de códigos de bytes. En Python 3 exec
no se pueden volver a enlazar los nombres locales de la función, y por lo tanto este SyntaxError y la ambigüedad no existen.
Un caso peculiar en Python 2 vs 3 compatibilidad es que mientras Python 2.7 documentation establece que
La forma exec(expr, globals)
es equivalente a exec expr in globals
, mientras que la forma exec(expr, globals, locals)
es equivalente a exec expr in globals, locals
. La forma de tupla de exec
proporciona compatibilidad con Python 3, donde exec
es una función en lugar de una declaración.
La forma de tupla no siempre ha sido 100% compatible, ya que hubo a bug in handling of exec
in functions with nested functions (issue 21591); hasta Python 2.7.8 el siguiente código podría haber arrojado una excepción:
def func():
exec('print "hi from test2"', {})
def subfunction():
return None
Esto se arregló en Python 2.7.9 y ya no arroja.
Existe la misma limitación con 'import * from ...'. – osa
me parece que las comprensiones dict se consideran subfunciones. – dbliss