Consider this working code:
x=123
def printx():
print(x)
If I execute printx()
the output would be 123
as x
value exists in locals()
and printx
sees that.
I can also get x
value like this:
locals()["x"]
But I need to run my function in exec with global and local parameters supplied, so I wrote this code, which should be identical in purpose to the first snippet:
glo = dict()
loc = dict()
exec('x=123', glo, loc)
exec('def printx():\n print(x)', glo, loc)
However, when I call printx()
I get this error:
exec('printx()', glo, loc)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
File "<string>", line 2, in printx
NameError: name 'x' is not defined
Yet both loc["x"]
and eval('x', glo, loc)
return 123
as expected.
How can I make locals and globals available for my printx
function?
I want printx
to behave the same in exec
with context?
If a local dict is provided, "eval" runs in that local namespace. All changes go in that local namespace. You can see that by printing
loc
after your commands. Bothx
andprintx
are in that namespace. Calling a function establishes a new local namespace. Python doesn't nest namespaces, so all it has available is its new (empty) local namespace and the global namespace, andx
is in neither of those.You should probably run your first two
eval
s with the global namespace only. That way, your code will work, even if it is a horrible way to do Python programming.