Is there a way in Python to add to the locals name-space by calling a function without explicitly assigning variables locally?
Something like the following for example (which of course doesn't work, because locals() return a copy of the local name-space) where the print statement would print '1'.
def A():
B(locals())
print x
def B(d):
d['x'] = 1
In Python 2.*
, you can disable the normal optimizations performed by the Python compiler regarding local variable access by starting your function with exec ''
; this will make the function very much slower (I just posted, earlier today, an answer showing how the local-variable optimization can easily speed code up by 3 or 4 times), but it will make your desired hack work. I.e., in Python 2.*:
def A():
exec ''
B(locals())
print x
def B(d):
d['x'] = 1
A()
will emit 1
, as you desire.
This hack was disabled in Python 3.*
(where exec
is just a function, not a statement nor a keyword any more) -- the compiler now performs the local variable optimization unconditionally, so there is no longer any way to work around it and make such hacks work.
Seems pretty horrible to rely on a hack like exec ''
. What about communicating like this with the global statement, it seems to work:
>>> def outer():
... global x
... b()
... print x
...
>>> def b():
... global x
... x = 2
...
>>> outer()
2
You could create a namespace for your variables instead:
class Namespace(object):
pass
def A():
names = Namespace()
B(names)
print names.x
def B(d):
d.x = 1
Then use names.x
or getattr(names, "x")
to access the attributes.