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

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

Helmut Jarausch
Guest
Posts: n/a

 12-01-2008
Hi,

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?

Many thanks for a hint,
Helmut.

--
Helmut Jarausch

Lehrstuhl fuer Numerische Mathematik
RWTH - Aachen University
D 52056 Aachen, Germany

Chris Rebert
Guest
Posts: n/a

 12-01-2008
On Mon, Dec 1, 2008 at 1:01 PM, Helmut Jarausch <(E-Mail Removed)> wrote:
> Hi,
>
> 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']

Could you explain what you mean by that? Your sample code doesn't seem
to do any "abbreviation"...
Otherwise I don't see why you don't just have a proper parameter list.

>
> 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?

>From the docs (http://docs.python.org/library/functions.html):

locals()
Update and return a dictionary representing the current local symbol table.
*Warning*:
The contents of this dictionary should not be modified; changes
may not affect the values of local variables used by the interpreter.
Free variables are returned by locals() when it is called in a
function block. Modifications of free variables may not affect the
values used by the interpreter. Free variables are not returned in
class blocks.

As the warning states, it modifying the dict doesn't really work
(except at the module level, but that's an implementation detail IIRC)
For example:
>>> def foo():

.... a = 3
.... l = locals()
.... l['a'] = 5
.... print a
....
>>> foo()

3

In any case, it'd be considered a bit of a hack.

Cheers,
Chris
--
Follow the path of the Iguana...
http://rebertia.com

>
> Many thanks for a hint,
> Helmut.
>
> --
> Helmut Jarausch
>
> Lehrstuhl fuer Numerische Mathematik
> RWTH - Aachen University
> D 52056 Aachen, Germany
> --
> http://mail.python.org/mailman/listinfo/python-list
>

Peter Otten
Guest
Posts: n/a

 12-01-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

Helmut Jarausch
Guest
Posts: n/a

 12-02-2008
Chris Rebert wrote:
> On Mon, Dec 1, 2008 at 1:01 PM, Helmut Jarausch <(E-Mail Removed)> wrote:
>> Hi,
>>
>> 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']

>
> Could you explain what you mean by that? Your sample code doesn't seem
> to do any "abbreviation"...
> Otherwise I don't see why you don't just have a proper parameter list.

In my application parms contains field names of an html form iff these fields
have been modified.
I'd like to use the short name _A instead of the longer expression parms['A']

--
Helmut Jarausch

Lehrstuhl fuer Numerische Mathematik
RWTH - Aachen University
D 52056 Aachen, Germany

Helmut Jarausch
Guest
Posts: n/a

 12-02-2008
Chris Rebert wrote:
> On Mon, Dec 1, 2008 at 1:01 PM, Helmut Jarausch <(E-Mail Removed)> wrote:
>> Hi,
>>
>> 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']

>
> Could you explain what you mean by that? Your sample code doesn't seem
> to do any "abbreviation"...
> Otherwise I don't see why you don't just have a proper parameter list.

In my application parms contains field names of an html form iff these fields
have been modified.
I'd like to use the short name _A instead of the longer expression parms['A']

--
Helmut Jarausch

Lehrstuhl fuer Numerische Mathematik
RWTH - Aachen University
D 52056 Aachen, Germany

Helmut Jarausch
Guest
Posts: n/a

 12-03-2008
Duncan Booth wrote:
> Helmut Jarausch <(E-Mail Removed)-aachen.de> wrote:
>
>> Chris Rebert wrote:
>>> On Mon, Dec 1, 2008 at 1:01 PM, Helmut Jarausch <(E-Mail Removed)>
>>> wrote:
>>>> Hi,
>>>>
>>>> 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']
>>> Could you explain what you mean by that? Your sample code doesn't
>>> seem to do any "abbreviation"...
>>> Otherwise I don't see why you don't just have a proper parameter
>>> list.

>> In my application parms contains field names of an html form iff these
>> fields have been modified.
>> I'd like to use the short name _A instead of the longer expression
>> parms['A']
>>
>>

> You haven't yet explained why you don't just do:
>
> def foo(A=None, **parms):
> ...
>
> The code to call foo remains the same as before, but Python will unpack
> the named parameter into the local variable A for you automatically. Any
> other parms that you didn't know about in advance remain in the separate
> dictionary.
>

Many thanks,
that's a very elegant solution.

Helmut.

--
Helmut Jarausch

Lehrstuhl fuer Numerische Mathematik
RWTH - Aachen University
D 52056 Aachen, Germany