It is not only a bad idea, as you put it - it simply won't work in Python.
At least not for a "local scope" for which "local" means a function scope.
TL;DR: If you "local scope" is a **module scope, just updating locals()
is enough. If your "local scope" is a function block, updating locals()
is ordinarily useless to create local variables dynamically. However, in Python 2, the use of exec
inside a function body will disable the fast locals optimization and the bytecode op used will be LOAD NAME
, which will match the vairbales defined in the exec
body. Therefore, inside a function, you have to resort to the exec
option (although, if the function contains a single exec statement, updating locals
should work, as the optimization is then disabled)
It can work for module scope (which is called global
in Python anyway), and
using class bodies as a naming scope.
That is because inside functions, local variables are used from fixed slots for speed reason, which shadow the mapping from names->local vars (the dictionary returned by locals()
.). So, if while you can create new "local variables" in the locals()
dict, if any attempt to access that variable is made in code in a line bellow that, in the same function body, that code will be compiled trying to get the variable from globals
instead - that is:
a = "global"
def b():
locals()["a"] = "local"
print(a)
Results in:
>>> b()
global
On the other hand, eval
is hardly needed - when you get a scope that will work, updating the proper dictionary already works. As mentioned above, a class body can be used for that, with the advantage that it will work as a namespace in a straightforward way:
>>> the_dict = {'x': '1', 'y': 'foo'}
>>> class A:
... locals().update(the_dict)
...
>>> A.x
'1'
>>> A.y
'foo'
And this is certainly "recomended". Just pay attention that there may be some side-effects of having a class created, in corner cases (if one of the objects in the dict have a __get__
method, for example, it will be used as a descriptor).