Python exec() function broken in versions above 2.7? Error: 'name' not definedWhat is the naming convention in Python for variable and function names?How to get a function name as a string in Python?Using exec() with recursive functionsCannot change global variables in a function through an exec() statement?What's the scope of a variable initialized in an if statement?Global name 'display' is not defined during “exec()”Behavior of exec function in Python 2 and Python 3Why doesn't a function defined using exec() know about names in the locals dict passed to exec()Python: variable defined by exec() not defined in a function scopePython: Nested function naming conflict
Why are MBA programs closing in the United States?
Assigning function to function pointer, const argument correctness?
How can one's career as a reviewer be ended?
Why Does Mama Coco Look Old After Going to the Other World?
That's not my X, its Y is too Z
Flat with smooth fibers implies formally smooth?
How do you play "tenth" chords on the guitar?
How can I write the maximally mixed state on m qubits as a linear combination of basis vectors
Is Lambda Calculus purely syntactic?
Extracting data from Plot
Can a human be transformed into a Mind Flayer?
Who is "He that flies" in Lord of the Rings?
Does the Nuka-Cola bottler actually generate nuka cola?
Make Gimbap cutter
Why did the World Bank set the global poverty line at $1.90?
How to write a convincing religious myth?
Trying to get (more) accurate readings from thermistor (electronics, math, and code inside)
Find the Missing Members of this Powered Sequence
Is it safe to remove python 2.7.15rc1 from Ubuntu 18.04?
Transfer custom ringtones to iPhone using a computer running Linux
Are polynomials with the same roots identical?
Analogy between an unknown in an argument, and a contradiction in the principle of explosion
Do empty drive bays need to be filled?
bash vs. zsh: What are the practical differences?
Python exec() function broken in versions above 2.7? Error: 'name' not defined
What is the naming convention in Python for variable and function names?How to get a function name as a string in Python?Using exec() with recursive functionsCannot change global variables in a function through an exec() statement?What's the scope of a variable initialized in an if statement?Global name 'display' is not defined during “exec()”Behavior of exec function in Python 2 and Python 3Why doesn't a function defined using exec() know about names in the locals dict passed to exec()Python: variable defined by exec() not defined in a function scopePython: Nested function naming conflict
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I've discovered a strange behaviour of python exec()
function. Here is the code:
variables =
('foo', 6),
('bar', 42)
def func():
for varData in variables:
varName, varValue = varData
localVarToEvaluate = varName + ' = varValue'
try:
#exec(localVarToEvaluate, globals(), locals())
exec(localVarToEvaluate)
except Exception as err:
print(str(err))
if varName not in locals():
print("Variable names '", varName, "can't be found in local scope!")
if 'foo' in locals():
print("'foo' OK:", foo) # exception here
else:
print("'foo' not available!")
if 'bar' in locals():
print("'bar' OK:", bar)
else:
print("'bar' not available!")
func()
I would expect variables foo
and bar
to be created and printed at the end by exec()
call, which is the case with Python 2.7. Everything above (tested on 3.3, 3.4, 3.6, and 3.7) throws exception, that foo
is not defined:
Exception has occurred: NameError
name 'foo' is not defined
Strange thing here is that foo
and bar
is seen by running locals()
, globals()
or dir()
(also confirmed by if
statements), however, it is not seen by the code/interpreter.
Even stranger, debugging this script and resolving any variable is successfull (I've set a breakpoint on # exception here
and type foo
in Debug window using VS Code. foo
is correctly resolved with a value of '6'.
If the same code (stuff inside function func()
) is not wrapped in function, this works as expected, foo
and bar
are printed out.
Any idea what is happening here?
UPDATE: I've further simplify this problem:
# take 1, create local variable 'foo' with value 6. Not in function.
varName = 'foo'
varValue = 42
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate)
except Exception as err:
print(str(err))
if 'foo' in locals():
# print(locals()['foo']) # (1)
# print(foo) # (2)
print("'foo' OK:", foo) # (3)
# take 2, create local variable 'bar' with value 42
def func2():
varName = 'bar'
varValue = 42
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate)
except Exception as err:
print(str(err))
if 'bar' in locals():
# print(locals()['bar']) # (1)
# print(bar) # (2)
#print("'bar' OK:", bar) # (3)
pass # uncomment any line above
func2()
When this code executes, first:
'foo' OK: 6
is printed, than this exception is raised:
Exception has occurred: NameError
name 'bar' is not defined
...
Note that both codes are identical, except that 'bar' variable is created inside function func2()
.
What I am interested in are not workarounds but explanation, why is this so and why points (1) works, while (2) and (3) does not. Note that bar
variable is seen in locals()
, while it is not accessible by directly calling it - but only if it is created inside function!
python python-3.x python-2.7 exec
add a comment |
I've discovered a strange behaviour of python exec()
function. Here is the code:
variables =
('foo', 6),
('bar', 42)
def func():
for varData in variables:
varName, varValue = varData
localVarToEvaluate = varName + ' = varValue'
try:
#exec(localVarToEvaluate, globals(), locals())
exec(localVarToEvaluate)
except Exception as err:
print(str(err))
if varName not in locals():
print("Variable names '", varName, "can't be found in local scope!")
if 'foo' in locals():
print("'foo' OK:", foo) # exception here
else:
print("'foo' not available!")
if 'bar' in locals():
print("'bar' OK:", bar)
else:
print("'bar' not available!")
func()
I would expect variables foo
and bar
to be created and printed at the end by exec()
call, which is the case with Python 2.7. Everything above (tested on 3.3, 3.4, 3.6, and 3.7) throws exception, that foo
is not defined:
Exception has occurred: NameError
name 'foo' is not defined
Strange thing here is that foo
and bar
is seen by running locals()
, globals()
or dir()
(also confirmed by if
statements), however, it is not seen by the code/interpreter.
Even stranger, debugging this script and resolving any variable is successfull (I've set a breakpoint on # exception here
and type foo
in Debug window using VS Code. foo
is correctly resolved with a value of '6'.
If the same code (stuff inside function func()
) is not wrapped in function, this works as expected, foo
and bar
are printed out.
Any idea what is happening here?
UPDATE: I've further simplify this problem:
# take 1, create local variable 'foo' with value 6. Not in function.
varName = 'foo'
varValue = 42
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate)
except Exception as err:
print(str(err))
if 'foo' in locals():
# print(locals()['foo']) # (1)
# print(foo) # (2)
print("'foo' OK:", foo) # (3)
# take 2, create local variable 'bar' with value 42
def func2():
varName = 'bar'
varValue = 42
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate)
except Exception as err:
print(str(err))
if 'bar' in locals():
# print(locals()['bar']) # (1)
# print(bar) # (2)
#print("'bar' OK:", bar) # (3)
pass # uncomment any line above
func2()
When this code executes, first:
'foo' OK: 6
is printed, than this exception is raised:
Exception has occurred: NameError
name 'bar' is not defined
...
Note that both codes are identical, except that 'bar' variable is created inside function func2()
.
What I am interested in are not workarounds but explanation, why is this so and why points (1) works, while (2) and (3) does not. Note that bar
variable is seen in locals()
, while it is not accessible by directly calling it - but only if it is created inside function!
python python-3.x python-2.7 exec
add a comment |
I've discovered a strange behaviour of python exec()
function. Here is the code:
variables =
('foo', 6),
('bar', 42)
def func():
for varData in variables:
varName, varValue = varData
localVarToEvaluate = varName + ' = varValue'
try:
#exec(localVarToEvaluate, globals(), locals())
exec(localVarToEvaluate)
except Exception as err:
print(str(err))
if varName not in locals():
print("Variable names '", varName, "can't be found in local scope!")
if 'foo' in locals():
print("'foo' OK:", foo) # exception here
else:
print("'foo' not available!")
if 'bar' in locals():
print("'bar' OK:", bar)
else:
print("'bar' not available!")
func()
I would expect variables foo
and bar
to be created and printed at the end by exec()
call, which is the case with Python 2.7. Everything above (tested on 3.3, 3.4, 3.6, and 3.7) throws exception, that foo
is not defined:
Exception has occurred: NameError
name 'foo' is not defined
Strange thing here is that foo
and bar
is seen by running locals()
, globals()
or dir()
(also confirmed by if
statements), however, it is not seen by the code/interpreter.
Even stranger, debugging this script and resolving any variable is successfull (I've set a breakpoint on # exception here
and type foo
in Debug window using VS Code. foo
is correctly resolved with a value of '6'.
If the same code (stuff inside function func()
) is not wrapped in function, this works as expected, foo
and bar
are printed out.
Any idea what is happening here?
UPDATE: I've further simplify this problem:
# take 1, create local variable 'foo' with value 6. Not in function.
varName = 'foo'
varValue = 42
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate)
except Exception as err:
print(str(err))
if 'foo' in locals():
# print(locals()['foo']) # (1)
# print(foo) # (2)
print("'foo' OK:", foo) # (3)
# take 2, create local variable 'bar' with value 42
def func2():
varName = 'bar'
varValue = 42
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate)
except Exception as err:
print(str(err))
if 'bar' in locals():
# print(locals()['bar']) # (1)
# print(bar) # (2)
#print("'bar' OK:", bar) # (3)
pass # uncomment any line above
func2()
When this code executes, first:
'foo' OK: 6
is printed, than this exception is raised:
Exception has occurred: NameError
name 'bar' is not defined
...
Note that both codes are identical, except that 'bar' variable is created inside function func2()
.
What I am interested in are not workarounds but explanation, why is this so and why points (1) works, while (2) and (3) does not. Note that bar
variable is seen in locals()
, while it is not accessible by directly calling it - but only if it is created inside function!
python python-3.x python-2.7 exec
I've discovered a strange behaviour of python exec()
function. Here is the code:
variables =
('foo', 6),
('bar', 42)
def func():
for varData in variables:
varName, varValue = varData
localVarToEvaluate = varName + ' = varValue'
try:
#exec(localVarToEvaluate, globals(), locals())
exec(localVarToEvaluate)
except Exception as err:
print(str(err))
if varName not in locals():
print("Variable names '", varName, "can't be found in local scope!")
if 'foo' in locals():
print("'foo' OK:", foo) # exception here
else:
print("'foo' not available!")
if 'bar' in locals():
print("'bar' OK:", bar)
else:
print("'bar' not available!")
func()
I would expect variables foo
and bar
to be created and printed at the end by exec()
call, which is the case with Python 2.7. Everything above (tested on 3.3, 3.4, 3.6, and 3.7) throws exception, that foo
is not defined:
Exception has occurred: NameError
name 'foo' is not defined
Strange thing here is that foo
and bar
is seen by running locals()
, globals()
or dir()
(also confirmed by if
statements), however, it is not seen by the code/interpreter.
Even stranger, debugging this script and resolving any variable is successfull (I've set a breakpoint on # exception here
and type foo
in Debug window using VS Code. foo
is correctly resolved with a value of '6'.
If the same code (stuff inside function func()
) is not wrapped in function, this works as expected, foo
and bar
are printed out.
Any idea what is happening here?
UPDATE: I've further simplify this problem:
# take 1, create local variable 'foo' with value 6. Not in function.
varName = 'foo'
varValue = 42
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate)
except Exception as err:
print(str(err))
if 'foo' in locals():
# print(locals()['foo']) # (1)
# print(foo) # (2)
print("'foo' OK:", foo) # (3)
# take 2, create local variable 'bar' with value 42
def func2():
varName = 'bar'
varValue = 42
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate)
except Exception as err:
print(str(err))
if 'bar' in locals():
# print(locals()['bar']) # (1)
# print(bar) # (2)
#print("'bar' OK:", bar) # (3)
pass # uncomment any line above
func2()
When this code executes, first:
'foo' OK: 6
is printed, than this exception is raised:
Exception has occurred: NameError
name 'bar' is not defined
...
Note that both codes are identical, except that 'bar' variable is created inside function func2()
.
What I am interested in are not workarounds but explanation, why is this so and why points (1) works, while (2) and (3) does not. Note that bar
variable is seen in locals()
, while it is not accessible by directly calling it - but only if it is created inside function!
python python-3.x python-2.7 exec
python python-3.x python-2.7 exec
edited Mar 21 at 13:36
schperplata
asked Mar 19 at 11:23
schperplataschperplata
94
94
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Lots of unclear issues about this question solved with OP. See answer edits. It boils down to (importing) hooking locals (variables, defs, classes) such that they are available for use inside a definition.
See answer below with inline comments what is what and why.
# take 1, create local variable 'foo' with value 6. Not in function.
# >>> code is executed in local-scope <<<
varName = 'foo'
varValue = 42
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate) # (0) dict item becomes varName : varValue
print (localVarToEvaluate) # (1) prints > foo = varValue < dict item
except Exception as err:
print(str(err))
if 'foo' in locals():
print(locals()['foo']) # (2) prints > 42 < value
print(foo) # (3) prints > 42 < value
print("'foo' OK:", foo) # (4) prints > 'foo' OK: 42 < stringtext, value
# take 2, create local variable 'bar' with value 42
def func2(self):
# >>> code executed inside function and not local-scope <<<
varName = 'bar'
varValue = 42
localVar2Evaluate = varName + ' = varValue'
try:
exec(localVar2Evaluate) # (5) dict item becomes varName : varValue
print (localVar2Evaluate) # (6) prints > bar = varValue < dict item
except Exception as err:
print(str(err))
print ('local-scope :', 'n', locals()) # (7) 'bar': 42, 'localVar2Evaluate': 'bar = varValue', 'varValue': 42, 'varName': 'bar'
if 'bar' in locals():
print(locals()['bar']) # (1)
print(bar) # (2) < --- python is not looking here in the locals() but inside the def for variable `bar` which is not made unless you give it access (hook or reference) via e.g. self.
print("'bar' OK:", bar) # (3)
# pass # uncomment any line above
x = 'a scotch... lets drink.. mystery solved!'
bar = "the local 'bar' variable is now available inside def func2().. It is: %s" % x
func2(bar)
As you can see I (import) create a hook to a local variable with varName 'bar' to be used inside the definition using self
. It can be any name t.b.h. See pydocs on self
, etc.
The result:
bar = varValue
local-scope :
'localVar2Evaluate': 'bar = varValue', 'varValue': 42, 'bar': 42, 'self': "the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!", 'varName': 'bar'
42
the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!
'bar' OK: the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!
If print('nn', locals())
below func() you get the following printresult:
- 'bar': "the local 'bar' variable is now available inside def
func2().. It is: a scotch... lets drink.. mistery solved!" - 'localVarToEvaluate': 'foo = varValue'
- 'varValue': 42
- 'foo': 42
- 'varName': 'foo'
- 'x': 'a scotch... lets drink.. mistery solved!'
- 'func2': "<"function func2 at 0x000002B070027F28">" # without " outside ">".
At bullet 7 you see func2 linked.
UPDATE 4:
Switching between python 2.7.16 and 3.5.2 revealed no change for the locals() dict and ONE change in the globals() dict as shown below.
In 2.7: 'variables': set([('bar', 42), ('foo', 6)])
In 3.5: 'variables': ('bar', 42), ('foo', 6)
... this set()
looks to me the reason why it no longer works what you addressed in 3.5.
I did test it with adapting your script:
import sys
print (sys.version)
variables = ('foo', 6), ('bar', 42)
def func():
for varData in variables:
varName, varValue = varData
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate)
print ('t2n', locals())
except Exception as err:
print(str(err))
if varName not in globals():
print("Variable names '", varName, "can't be found in global scope!")
if 'foo' in globals():
print("'foo' OK:", foo) # exception here
else:
print("'foo' not available!")
if 'bar' in globals():
print("'bar' OK:", bar)
else:
print("'bar' not available!")
print ('t1n', globals())
func()
Then ... it could still be exec. So I disabled running func()
and the difference in globals()
remained. SO I think its a difference in globals()
function, rather exec
.
I am not sure what you mean. Of coursefoo
does not exist jet, this is the whole point of doingexec()
. The interesting part of this code blocklang-py if 'foo' in locals(): print("'foo' OK:", foo) # exception here
is thatfoo
variable is created and can be seen inlocals()
, but when I try to print it out, interpreter knows nothing about it. What do you mean by: ... because 'foo' is in your script just a text variable and not a list or tuple container.?
– schperplata
Mar 20 at 6:42
see update and inline comment.
– ZF007
Mar 20 at 7:43
I've updated the issue description. Note that I'am not interested in workarounds, but in explanation. Thank you!
– schperplata
Mar 21 at 13:36
Thank you for your effort, but I still don't see how this has anything to do with my question. Why isexec()
call working outside func2, and why I can seebar
variable in locals():'bar' (1908669175152):42
while python still can't see it?
– schperplata
Mar 22 at 10:25
I've added a bunch of lines with in a particular execution order. This way you can see that you are still confusing things. In particular, you're mixing up stringtext with variable names in the locals scope. Check the arrow where it goes wrong with your assumption of what you think you are seeing. For more in-depth info check python docs for :variables, objects, pointers, id() and built-in functions. Thegetattr
andsetattr
are the right tools to create variables on-the-fly as the first part of your question pointed towards.
– ZF007
Mar 22 at 15:25
|
show 7 more comments
I've reported a bug on a Python Issue Tracker, and the official answer is:
This is currently by design, which means 3.8 is likely the only viable place it can change. It's also not Windows specific so I removed that component (people may remove themselves from nosy).
...
Currently it's basically a read-only proxy, as locals are optimized within functions which is why you can't see updates via the duct.
Bottom line, exec()
used in this way is useless inside functions.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55239875%2fpython-exec-function-broken-in-versions-above-2-7-error-name-not-defined%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Lots of unclear issues about this question solved with OP. See answer edits. It boils down to (importing) hooking locals (variables, defs, classes) such that they are available for use inside a definition.
See answer below with inline comments what is what and why.
# take 1, create local variable 'foo' with value 6. Not in function.
# >>> code is executed in local-scope <<<
varName = 'foo'
varValue = 42
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate) # (0) dict item becomes varName : varValue
print (localVarToEvaluate) # (1) prints > foo = varValue < dict item
except Exception as err:
print(str(err))
if 'foo' in locals():
print(locals()['foo']) # (2) prints > 42 < value
print(foo) # (3) prints > 42 < value
print("'foo' OK:", foo) # (4) prints > 'foo' OK: 42 < stringtext, value
# take 2, create local variable 'bar' with value 42
def func2(self):
# >>> code executed inside function and not local-scope <<<
varName = 'bar'
varValue = 42
localVar2Evaluate = varName + ' = varValue'
try:
exec(localVar2Evaluate) # (5) dict item becomes varName : varValue
print (localVar2Evaluate) # (6) prints > bar = varValue < dict item
except Exception as err:
print(str(err))
print ('local-scope :', 'n', locals()) # (7) 'bar': 42, 'localVar2Evaluate': 'bar = varValue', 'varValue': 42, 'varName': 'bar'
if 'bar' in locals():
print(locals()['bar']) # (1)
print(bar) # (2) < --- python is not looking here in the locals() but inside the def for variable `bar` which is not made unless you give it access (hook or reference) via e.g. self.
print("'bar' OK:", bar) # (3)
# pass # uncomment any line above
x = 'a scotch... lets drink.. mystery solved!'
bar = "the local 'bar' variable is now available inside def func2().. It is: %s" % x
func2(bar)
As you can see I (import) create a hook to a local variable with varName 'bar' to be used inside the definition using self
. It can be any name t.b.h. See pydocs on self
, etc.
The result:
bar = varValue
local-scope :
'localVar2Evaluate': 'bar = varValue', 'varValue': 42, 'bar': 42, 'self': "the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!", 'varName': 'bar'
42
the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!
'bar' OK: the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!
If print('nn', locals())
below func() you get the following printresult:
- 'bar': "the local 'bar' variable is now available inside def
func2().. It is: a scotch... lets drink.. mistery solved!" - 'localVarToEvaluate': 'foo = varValue'
- 'varValue': 42
- 'foo': 42
- 'varName': 'foo'
- 'x': 'a scotch... lets drink.. mistery solved!'
- 'func2': "<"function func2 at 0x000002B070027F28">" # without " outside ">".
At bullet 7 you see func2 linked.
UPDATE 4:
Switching between python 2.7.16 and 3.5.2 revealed no change for the locals() dict and ONE change in the globals() dict as shown below.
In 2.7: 'variables': set([('bar', 42), ('foo', 6)])
In 3.5: 'variables': ('bar', 42), ('foo', 6)
... this set()
looks to me the reason why it no longer works what you addressed in 3.5.
I did test it with adapting your script:
import sys
print (sys.version)
variables = ('foo', 6), ('bar', 42)
def func():
for varData in variables:
varName, varValue = varData
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate)
print ('t2n', locals())
except Exception as err:
print(str(err))
if varName not in globals():
print("Variable names '", varName, "can't be found in global scope!")
if 'foo' in globals():
print("'foo' OK:", foo) # exception here
else:
print("'foo' not available!")
if 'bar' in globals():
print("'bar' OK:", bar)
else:
print("'bar' not available!")
print ('t1n', globals())
func()
Then ... it could still be exec. So I disabled running func()
and the difference in globals()
remained. SO I think its a difference in globals()
function, rather exec
.
I am not sure what you mean. Of coursefoo
does not exist jet, this is the whole point of doingexec()
. The interesting part of this code blocklang-py if 'foo' in locals(): print("'foo' OK:", foo) # exception here
is thatfoo
variable is created and can be seen inlocals()
, but when I try to print it out, interpreter knows nothing about it. What do you mean by: ... because 'foo' is in your script just a text variable and not a list or tuple container.?
– schperplata
Mar 20 at 6:42
see update and inline comment.
– ZF007
Mar 20 at 7:43
I've updated the issue description. Note that I'am not interested in workarounds, but in explanation. Thank you!
– schperplata
Mar 21 at 13:36
Thank you for your effort, but I still don't see how this has anything to do with my question. Why isexec()
call working outside func2, and why I can seebar
variable in locals():'bar' (1908669175152):42
while python still can't see it?
– schperplata
Mar 22 at 10:25
I've added a bunch of lines with in a particular execution order. This way you can see that you are still confusing things. In particular, you're mixing up stringtext with variable names in the locals scope. Check the arrow where it goes wrong with your assumption of what you think you are seeing. For more in-depth info check python docs for :variables, objects, pointers, id() and built-in functions. Thegetattr
andsetattr
are the right tools to create variables on-the-fly as the first part of your question pointed towards.
– ZF007
Mar 22 at 15:25
|
show 7 more comments
Lots of unclear issues about this question solved with OP. See answer edits. It boils down to (importing) hooking locals (variables, defs, classes) such that they are available for use inside a definition.
See answer below with inline comments what is what and why.
# take 1, create local variable 'foo' with value 6. Not in function.
# >>> code is executed in local-scope <<<
varName = 'foo'
varValue = 42
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate) # (0) dict item becomes varName : varValue
print (localVarToEvaluate) # (1) prints > foo = varValue < dict item
except Exception as err:
print(str(err))
if 'foo' in locals():
print(locals()['foo']) # (2) prints > 42 < value
print(foo) # (3) prints > 42 < value
print("'foo' OK:", foo) # (4) prints > 'foo' OK: 42 < stringtext, value
# take 2, create local variable 'bar' with value 42
def func2(self):
# >>> code executed inside function and not local-scope <<<
varName = 'bar'
varValue = 42
localVar2Evaluate = varName + ' = varValue'
try:
exec(localVar2Evaluate) # (5) dict item becomes varName : varValue
print (localVar2Evaluate) # (6) prints > bar = varValue < dict item
except Exception as err:
print(str(err))
print ('local-scope :', 'n', locals()) # (7) 'bar': 42, 'localVar2Evaluate': 'bar = varValue', 'varValue': 42, 'varName': 'bar'
if 'bar' in locals():
print(locals()['bar']) # (1)
print(bar) # (2) < --- python is not looking here in the locals() but inside the def for variable `bar` which is not made unless you give it access (hook or reference) via e.g. self.
print("'bar' OK:", bar) # (3)
# pass # uncomment any line above
x = 'a scotch... lets drink.. mystery solved!'
bar = "the local 'bar' variable is now available inside def func2().. It is: %s" % x
func2(bar)
As you can see I (import) create a hook to a local variable with varName 'bar' to be used inside the definition using self
. It can be any name t.b.h. See pydocs on self
, etc.
The result:
bar = varValue
local-scope :
'localVar2Evaluate': 'bar = varValue', 'varValue': 42, 'bar': 42, 'self': "the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!", 'varName': 'bar'
42
the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!
'bar' OK: the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!
If print('nn', locals())
below func() you get the following printresult:
- 'bar': "the local 'bar' variable is now available inside def
func2().. It is: a scotch... lets drink.. mistery solved!" - 'localVarToEvaluate': 'foo = varValue'
- 'varValue': 42
- 'foo': 42
- 'varName': 'foo'
- 'x': 'a scotch... lets drink.. mistery solved!'
- 'func2': "<"function func2 at 0x000002B070027F28">" # without " outside ">".
At bullet 7 you see func2 linked.
UPDATE 4:
Switching between python 2.7.16 and 3.5.2 revealed no change for the locals() dict and ONE change in the globals() dict as shown below.
In 2.7: 'variables': set([('bar', 42), ('foo', 6)])
In 3.5: 'variables': ('bar', 42), ('foo', 6)
... this set()
looks to me the reason why it no longer works what you addressed in 3.5.
I did test it with adapting your script:
import sys
print (sys.version)
variables = ('foo', 6), ('bar', 42)
def func():
for varData in variables:
varName, varValue = varData
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate)
print ('t2n', locals())
except Exception as err:
print(str(err))
if varName not in globals():
print("Variable names '", varName, "can't be found in global scope!")
if 'foo' in globals():
print("'foo' OK:", foo) # exception here
else:
print("'foo' not available!")
if 'bar' in globals():
print("'bar' OK:", bar)
else:
print("'bar' not available!")
print ('t1n', globals())
func()
Then ... it could still be exec. So I disabled running func()
and the difference in globals()
remained. SO I think its a difference in globals()
function, rather exec
.
I am not sure what you mean. Of coursefoo
does not exist jet, this is the whole point of doingexec()
. The interesting part of this code blocklang-py if 'foo' in locals(): print("'foo' OK:", foo) # exception here
is thatfoo
variable is created and can be seen inlocals()
, but when I try to print it out, interpreter knows nothing about it. What do you mean by: ... because 'foo' is in your script just a text variable and not a list or tuple container.?
– schperplata
Mar 20 at 6:42
see update and inline comment.
– ZF007
Mar 20 at 7:43
I've updated the issue description. Note that I'am not interested in workarounds, but in explanation. Thank you!
– schperplata
Mar 21 at 13:36
Thank you for your effort, but I still don't see how this has anything to do with my question. Why isexec()
call working outside func2, and why I can seebar
variable in locals():'bar' (1908669175152):42
while python still can't see it?
– schperplata
Mar 22 at 10:25
I've added a bunch of lines with in a particular execution order. This way you can see that you are still confusing things. In particular, you're mixing up stringtext with variable names in the locals scope. Check the arrow where it goes wrong with your assumption of what you think you are seeing. For more in-depth info check python docs for :variables, objects, pointers, id() and built-in functions. Thegetattr
andsetattr
are the right tools to create variables on-the-fly as the first part of your question pointed towards.
– ZF007
Mar 22 at 15:25
|
show 7 more comments
Lots of unclear issues about this question solved with OP. See answer edits. It boils down to (importing) hooking locals (variables, defs, classes) such that they are available for use inside a definition.
See answer below with inline comments what is what and why.
# take 1, create local variable 'foo' with value 6. Not in function.
# >>> code is executed in local-scope <<<
varName = 'foo'
varValue = 42
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate) # (0) dict item becomes varName : varValue
print (localVarToEvaluate) # (1) prints > foo = varValue < dict item
except Exception as err:
print(str(err))
if 'foo' in locals():
print(locals()['foo']) # (2) prints > 42 < value
print(foo) # (3) prints > 42 < value
print("'foo' OK:", foo) # (4) prints > 'foo' OK: 42 < stringtext, value
# take 2, create local variable 'bar' with value 42
def func2(self):
# >>> code executed inside function and not local-scope <<<
varName = 'bar'
varValue = 42
localVar2Evaluate = varName + ' = varValue'
try:
exec(localVar2Evaluate) # (5) dict item becomes varName : varValue
print (localVar2Evaluate) # (6) prints > bar = varValue < dict item
except Exception as err:
print(str(err))
print ('local-scope :', 'n', locals()) # (7) 'bar': 42, 'localVar2Evaluate': 'bar = varValue', 'varValue': 42, 'varName': 'bar'
if 'bar' in locals():
print(locals()['bar']) # (1)
print(bar) # (2) < --- python is not looking here in the locals() but inside the def for variable `bar` which is not made unless you give it access (hook or reference) via e.g. self.
print("'bar' OK:", bar) # (3)
# pass # uncomment any line above
x = 'a scotch... lets drink.. mystery solved!'
bar = "the local 'bar' variable is now available inside def func2().. It is: %s" % x
func2(bar)
As you can see I (import) create a hook to a local variable with varName 'bar' to be used inside the definition using self
. It can be any name t.b.h. See pydocs on self
, etc.
The result:
bar = varValue
local-scope :
'localVar2Evaluate': 'bar = varValue', 'varValue': 42, 'bar': 42, 'self': "the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!", 'varName': 'bar'
42
the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!
'bar' OK: the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!
If print('nn', locals())
below func() you get the following printresult:
- 'bar': "the local 'bar' variable is now available inside def
func2().. It is: a scotch... lets drink.. mistery solved!" - 'localVarToEvaluate': 'foo = varValue'
- 'varValue': 42
- 'foo': 42
- 'varName': 'foo'
- 'x': 'a scotch... lets drink.. mistery solved!'
- 'func2': "<"function func2 at 0x000002B070027F28">" # without " outside ">".
At bullet 7 you see func2 linked.
UPDATE 4:
Switching between python 2.7.16 and 3.5.2 revealed no change for the locals() dict and ONE change in the globals() dict as shown below.
In 2.7: 'variables': set([('bar', 42), ('foo', 6)])
In 3.5: 'variables': ('bar', 42), ('foo', 6)
... this set()
looks to me the reason why it no longer works what you addressed in 3.5.
I did test it with adapting your script:
import sys
print (sys.version)
variables = ('foo', 6), ('bar', 42)
def func():
for varData in variables:
varName, varValue = varData
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate)
print ('t2n', locals())
except Exception as err:
print(str(err))
if varName not in globals():
print("Variable names '", varName, "can't be found in global scope!")
if 'foo' in globals():
print("'foo' OK:", foo) # exception here
else:
print("'foo' not available!")
if 'bar' in globals():
print("'bar' OK:", bar)
else:
print("'bar' not available!")
print ('t1n', globals())
func()
Then ... it could still be exec. So I disabled running func()
and the difference in globals()
remained. SO I think its a difference in globals()
function, rather exec
.
Lots of unclear issues about this question solved with OP. See answer edits. It boils down to (importing) hooking locals (variables, defs, classes) such that they are available for use inside a definition.
See answer below with inline comments what is what and why.
# take 1, create local variable 'foo' with value 6. Not in function.
# >>> code is executed in local-scope <<<
varName = 'foo'
varValue = 42
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate) # (0) dict item becomes varName : varValue
print (localVarToEvaluate) # (1) prints > foo = varValue < dict item
except Exception as err:
print(str(err))
if 'foo' in locals():
print(locals()['foo']) # (2) prints > 42 < value
print(foo) # (3) prints > 42 < value
print("'foo' OK:", foo) # (4) prints > 'foo' OK: 42 < stringtext, value
# take 2, create local variable 'bar' with value 42
def func2(self):
# >>> code executed inside function and not local-scope <<<
varName = 'bar'
varValue = 42
localVar2Evaluate = varName + ' = varValue'
try:
exec(localVar2Evaluate) # (5) dict item becomes varName : varValue
print (localVar2Evaluate) # (6) prints > bar = varValue < dict item
except Exception as err:
print(str(err))
print ('local-scope :', 'n', locals()) # (7) 'bar': 42, 'localVar2Evaluate': 'bar = varValue', 'varValue': 42, 'varName': 'bar'
if 'bar' in locals():
print(locals()['bar']) # (1)
print(bar) # (2) < --- python is not looking here in the locals() but inside the def for variable `bar` which is not made unless you give it access (hook or reference) via e.g. self.
print("'bar' OK:", bar) # (3)
# pass # uncomment any line above
x = 'a scotch... lets drink.. mystery solved!'
bar = "the local 'bar' variable is now available inside def func2().. It is: %s" % x
func2(bar)
As you can see I (import) create a hook to a local variable with varName 'bar' to be used inside the definition using self
. It can be any name t.b.h. See pydocs on self
, etc.
The result:
bar = varValue
local-scope :
'localVar2Evaluate': 'bar = varValue', 'varValue': 42, 'bar': 42, 'self': "the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!", 'varName': 'bar'
42
the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!
'bar' OK: the local 'bar' variable is now available inside def func2().. It is: a scotch... lets drink.. mystery solved!
If print('nn', locals())
below func() you get the following printresult:
- 'bar': "the local 'bar' variable is now available inside def
func2().. It is: a scotch... lets drink.. mistery solved!" - 'localVarToEvaluate': 'foo = varValue'
- 'varValue': 42
- 'foo': 42
- 'varName': 'foo'
- 'x': 'a scotch... lets drink.. mistery solved!'
- 'func2': "<"function func2 at 0x000002B070027F28">" # without " outside ">".
At bullet 7 you see func2 linked.
UPDATE 4:
Switching between python 2.7.16 and 3.5.2 revealed no change for the locals() dict and ONE change in the globals() dict as shown below.
In 2.7: 'variables': set([('bar', 42), ('foo', 6)])
In 3.5: 'variables': ('bar', 42), ('foo', 6)
... this set()
looks to me the reason why it no longer works what you addressed in 3.5.
I did test it with adapting your script:
import sys
print (sys.version)
variables = ('foo', 6), ('bar', 42)
def func():
for varData in variables:
varName, varValue = varData
localVarToEvaluate = varName + ' = varValue'
try:
exec(localVarToEvaluate)
print ('t2n', locals())
except Exception as err:
print(str(err))
if varName not in globals():
print("Variable names '", varName, "can't be found in global scope!")
if 'foo' in globals():
print("'foo' OK:", foo) # exception here
else:
print("'foo' not available!")
if 'bar' in globals():
print("'bar' OK:", bar)
else:
print("'bar' not available!")
print ('t1n', globals())
func()
Then ... it could still be exec. So I disabled running func()
and the difference in globals()
remained. SO I think its a difference in globals()
function, rather exec
.
edited Mar 24 at 21:57
answered Mar 19 at 11:29
ZF007ZF007
1,98731329
1,98731329
I am not sure what you mean. Of coursefoo
does not exist jet, this is the whole point of doingexec()
. The interesting part of this code blocklang-py if 'foo' in locals(): print("'foo' OK:", foo) # exception here
is thatfoo
variable is created and can be seen inlocals()
, but when I try to print it out, interpreter knows nothing about it. What do you mean by: ... because 'foo' is in your script just a text variable and not a list or tuple container.?
– schperplata
Mar 20 at 6:42
see update and inline comment.
– ZF007
Mar 20 at 7:43
I've updated the issue description. Note that I'am not interested in workarounds, but in explanation. Thank you!
– schperplata
Mar 21 at 13:36
Thank you for your effort, but I still don't see how this has anything to do with my question. Why isexec()
call working outside func2, and why I can seebar
variable in locals():'bar' (1908669175152):42
while python still can't see it?
– schperplata
Mar 22 at 10:25
I've added a bunch of lines with in a particular execution order. This way you can see that you are still confusing things. In particular, you're mixing up stringtext with variable names in the locals scope. Check the arrow where it goes wrong with your assumption of what you think you are seeing. For more in-depth info check python docs for :variables, objects, pointers, id() and built-in functions. Thegetattr
andsetattr
are the right tools to create variables on-the-fly as the first part of your question pointed towards.
– ZF007
Mar 22 at 15:25
|
show 7 more comments
I am not sure what you mean. Of coursefoo
does not exist jet, this is the whole point of doingexec()
. The interesting part of this code blocklang-py if 'foo' in locals(): print("'foo' OK:", foo) # exception here
is thatfoo
variable is created and can be seen inlocals()
, but when I try to print it out, interpreter knows nothing about it. What do you mean by: ... because 'foo' is in your script just a text variable and not a list or tuple container.?
– schperplata
Mar 20 at 6:42
see update and inline comment.
– ZF007
Mar 20 at 7:43
I've updated the issue description. Note that I'am not interested in workarounds, but in explanation. Thank you!
– schperplata
Mar 21 at 13:36
Thank you for your effort, but I still don't see how this has anything to do with my question. Why isexec()
call working outside func2, and why I can seebar
variable in locals():'bar' (1908669175152):42
while python still can't see it?
– schperplata
Mar 22 at 10:25
I've added a bunch of lines with in a particular execution order. This way you can see that you are still confusing things. In particular, you're mixing up stringtext with variable names in the locals scope. Check the arrow where it goes wrong with your assumption of what you think you are seeing. For more in-depth info check python docs for :variables, objects, pointers, id() and built-in functions. Thegetattr
andsetattr
are the right tools to create variables on-the-fly as the first part of your question pointed towards.
– ZF007
Mar 22 at 15:25
I am not sure what you mean. Of course
foo
does not exist jet, this is the whole point of doing exec()
. The interesting part of this code block lang-py if 'foo' in locals(): print("'foo' OK:", foo) # exception here
is that foo
variable is created and can be seen in locals()
, but when I try to print it out, interpreter knows nothing about it. What do you mean by: ... because 'foo' is in your script just a text variable and not a list or tuple container.?– schperplata
Mar 20 at 6:42
I am not sure what you mean. Of course
foo
does not exist jet, this is the whole point of doing exec()
. The interesting part of this code block lang-py if 'foo' in locals(): print("'foo' OK:", foo) # exception here
is that foo
variable is created and can be seen in locals()
, but when I try to print it out, interpreter knows nothing about it. What do you mean by: ... because 'foo' is in your script just a text variable and not a list or tuple container.?– schperplata
Mar 20 at 6:42
see update and inline comment.
– ZF007
Mar 20 at 7:43
see update and inline comment.
– ZF007
Mar 20 at 7:43
I've updated the issue description. Note that I'am not interested in workarounds, but in explanation. Thank you!
– schperplata
Mar 21 at 13:36
I've updated the issue description. Note that I'am not interested in workarounds, but in explanation. Thank you!
– schperplata
Mar 21 at 13:36
Thank you for your effort, but I still don't see how this has anything to do with my question. Why is
exec()
call working outside func2, and why I can see bar
variable in locals(): 'bar' (1908669175152):42
while python still can't see it?– schperplata
Mar 22 at 10:25
Thank you for your effort, but I still don't see how this has anything to do with my question. Why is
exec()
call working outside func2, and why I can see bar
variable in locals(): 'bar' (1908669175152):42
while python still can't see it?– schperplata
Mar 22 at 10:25
I've added a bunch of lines with in a particular execution order. This way you can see that you are still confusing things. In particular, you're mixing up stringtext with variable names in the locals scope. Check the arrow where it goes wrong with your assumption of what you think you are seeing. For more in-depth info check python docs for :variables, objects, pointers, id() and built-in functions. The
getattr
and setattr
are the right tools to create variables on-the-fly as the first part of your question pointed towards.– ZF007
Mar 22 at 15:25
I've added a bunch of lines with in a particular execution order. This way you can see that you are still confusing things. In particular, you're mixing up stringtext with variable names in the locals scope. Check the arrow where it goes wrong with your assumption of what you think you are seeing. For more in-depth info check python docs for :variables, objects, pointers, id() and built-in functions. The
getattr
and setattr
are the right tools to create variables on-the-fly as the first part of your question pointed towards.– ZF007
Mar 22 at 15:25
|
show 7 more comments
I've reported a bug on a Python Issue Tracker, and the official answer is:
This is currently by design, which means 3.8 is likely the only viable place it can change. It's also not Windows specific so I removed that component (people may remove themselves from nosy).
...
Currently it's basically a read-only proxy, as locals are optimized within functions which is why you can't see updates via the duct.
Bottom line, exec()
used in this way is useless inside functions.
add a comment |
I've reported a bug on a Python Issue Tracker, and the official answer is:
This is currently by design, which means 3.8 is likely the only viable place it can change. It's also not Windows specific so I removed that component (people may remove themselves from nosy).
...
Currently it's basically a read-only proxy, as locals are optimized within functions which is why you can't see updates via the duct.
Bottom line, exec()
used in this way is useless inside functions.
add a comment |
I've reported a bug on a Python Issue Tracker, and the official answer is:
This is currently by design, which means 3.8 is likely the only viable place it can change. It's also not Windows specific so I removed that component (people may remove themselves from nosy).
...
Currently it's basically a read-only proxy, as locals are optimized within functions which is why you can't see updates via the duct.
Bottom line, exec()
used in this way is useless inside functions.
I've reported a bug on a Python Issue Tracker, and the official answer is:
This is currently by design, which means 3.8 is likely the only viable place it can change. It's also not Windows specific so I removed that component (people may remove themselves from nosy).
...
Currently it's basically a read-only proxy, as locals are optimized within functions which is why you can't see updates via the duct.
Bottom line, exec()
used in this way is useless inside functions.
answered Mar 26 at 6:57
schperplataschperplata
94
94
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55239875%2fpython-exec-function-broken-in-versions-above-2-7-error-name-not-defined%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown