Is it safe to modify the dict returned by vars() or locals()

Peter Otten __peter__ at web.de
Mon Dec 1 16:25:30 EST 2008


Helmut Jarausch wrote:

> I am looking for an elegant way to solve the following problem:
> 
> Within a function
> 
> def Foo(**parms)
> 
> I have a list of names, say  VList=['A','B','C1']
> and I like to generate abbreviation
> _A identical to parms['A']
> 
> for that I could write
> 
> def Foo(**parms) :
>    for N in VList :
>      if  N in parms :
>        vars()[N]= parms[N]
>      else :
>        vars()[N]= None
> 
> Does this work, is it typical Python?

locals() gives you a copy of the local namespace. No changes to the copy are
written back to that namespace. 

In idiomatic python you'd just use the dictionary. If you are bothered with
the non-existent keys, make a copy

>>> parms = dict(a=1, c=3)
>>> p = dict.fromkeys(["a", "b", "c"])
>>> p.update(parms)
>>> p["a"], p["b"], p["c"]
(1, None, 3)
>>> p["x"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'x'

or, setting any non-existent key to None:

>>> from collections import defaultdict
>>> parms = dict(a=1, c=3)
>>> p = defaultdict(lambda: None)
>>> p.update(parms)
>>> p["a"], p["b"], p["c"]
(1, None, 3)

If you insist on manipulating the namespace you can use exec:

>>> def foo(**parms):
...     exec "\n".join("%s = parms.get(%r)" % (n, n) for n in
["a", "b", "c"])
...     return a, b, c
...
>>> foo(a=1, c=3)
(1, None, 3)
>>> foo(b=20)
(None, 20, None)

Peter



More information about the Python-list mailing list