updating local()

Duncan Booth duncan.booth at invalid.invalid
Wed Oct 5 18:52:47 CEST 2005


Flavio wrote:
> Can anyone tell me why, if the following code works, I should not do
> this?
> 
> #
> # Extending Local namespace
> #
> 
> def fun(a=1,b=2,**args):
> 
>      print 'locals:',locals()
>      locals().update(args)
>      print locals()
> 
> e = {'s':3,'e':4}
> fun(k=10,v=32,**e)
> 
Because if all you want is to update a dictionary you might as well use 
another dictionary which isn't locals(). If what you want is to update the 
local variables, that won't work:

>>> def fun(a=1,b=2,**args):
        s = 1
	print 'locals:',locals()
	locals().update(args)
	print locals()
	print s, e

	
>>> e = {'s':3,'e':4}
>>> fun(k=10,v=32,**e)
locals: {'a': 1, 's': 1, 'args': {'s': 3, 'e': 4, 'k': 10, 'v': 32}, 'b': 
2}
{'a': 1, 'b': 2, 'e': 4, 'k': 10, 'args': {'s': 3, 'e': 4, 'k': 10, 'v': 
32}, 's': 1, 'v': 32}
1 {'s': 3, 'e': 4}
>>> 

Note that k, v, and e are added to the locals dictionary, but real local 
variables such as 's' are not updated. Also you cannot access k, v, and e 
as local variables within the function, if you try you get the global 
variables (if they exist).

Also, this behaviour is undefined. Different versions of Python will behave 
differently, and even minor code changes can change the behaviour. With 
this version, 's' still doesn't update, but we can now access the 'e' value 
as a variable:

>>> def fun(a=1,b=2,**args):
        s = 1
	print 'locals:',locals()
	locals().update(args)
	print locals()
	exec "print 'hi'"
	print s,e

	
>>> fun(k=10,v=32,**e)
locals: {'a': 1, 's': 1, 'args': {'s': 3, 'e': 4, 'k': 10, 'v': 32}, 'b': 
2}
{'a': 1, 'b': 2, 'e': 4, 'k': 10, 'args': {'s': 3, 'e': 4, 'k': 10, 'v': 
32}, 's': 1, 'v': 32}
hi
1 4
>>> 

Short answer: don't even think of trying to update locals().



More information about the Python-list mailing list