I need to assign some variables when calling a funcion with the name of the variable as an argument.
Therefore, I loop through a tuple with the desired names, assigning them via the locals() dict.
It works, but then I can't access them by name - even inside the function itself.
def function():
var_names = ("foo","bar","foobar")
for var_name in var_names:
locals()[var_name] = len(var_name)
print foo
Throws:
Traceback (most recent call last):
File "error_test.py", line 8, in <module>
function()
File "error_test.py", line 5, in function
print foo
NameError: global name 'foo' is not defined
With the following code it works well:
def function():
var_names = ("foo","bar","foobar")
for var_name in var_names:
locals()[var_name] = len(var_name)
print locals()["foo"]
Isn't it that the locals() dict contains just the normal function variables? Why isn't it working?
When you write:
for var_name in var_names:
locals()[var_name] = len(var_name)
You modify the locals() dictionary:
as @user2357112 aptly linked in the docs:
Note
The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.
So modifying locals() deletes the local variables, hence the NameError: global name 'foo' is not defined error.
Quoting this post, the explanation seems to be that inside the function you're only retrieving a copy of the namespace and not the namespace itself:
locals does not actually return the local namespace, it returns a copy. So changing it does nothing to the value of the variables in the local namespace.
I'm still looking for a way to change that namespace inside a function, so I'd love to see someone answer this question with a better solution than this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With