When I run this code:
a = '1'
vars()['a'] = '2'
print a
I get the following output:
2
But when I run this code:
def bar():
a = '1'
vars()['a'] = '2'
print a
bar()
I get the following output:
1
Now my question is why does that happen and how can I make the second case give me the same solution as the first case.
Edit:
Couldn't really find a solution but I found a small hack around it... Though I'll rather not use exec:
def bar():
a = "a"
b = "b"
exec a+"="+b
print a
bar()
Which gets me the outcome:
b
If anyone can find a better solution then it would be great. I'm not setting any global variables this way or doing anything crazy so don't worry about that.
It looks like new style classes override the default __dict__ behavior and thus break this useage of vars(). Not certain why it would impact old style classes, but it might be related.
From docs (http://docs.python.org/library/functions.html#vars):
vars([object])
Return the __dict__ attribute for a module, class, instance, or any other object with a __dict__ attribute.
Objects such as modules and instances have an updateable __dict__ attribute; however, other objects may have write restrictions on their __dict__ attributes (for example, new-style classes use a dictproxy to prevent direct dictionary updates).
Without an argument, vars() acts like locals(). Note, the locals dictionary is only useful for reads since updates to the locals dictionary are ignored.
Could you perhaps comment on why self. = val or setattr(self, 'x', val) won't work for your class case?
Assignment to the result of vars() is not defined. So it might give different results in different scenarios and/or python versions and/or implementations. Though it might sound appalling to be able to change local variables using this way (I tried using it for regex groupdict results once), this is highly unportable and might break any time.
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