Re: Python3 exec locals - this must be a FAQ

Discussion in 'Python' started by MRAB, Feb 12, 2013.

  1. MRAB

    MRAB Guest

    On 2013-02-12 13:27, Dave Angel wrote:
    > On 02/12/2013 06:46 AM, Helmut Jarausch wrote:
    >> Hi,
    >>
    >> I've tried but didn't find an answer on the net.
    >>
    >> The exec function in Python modifies a copy of locals() only.
    >> How can I transfer changes in that local copy to the locals of my function
    >> ** without ** knowing the names of these variables.
    >>
    >> E.g. I have a lot of local names.
    >>
    >> Doing
    >>
    >> _locals= locals()

    >
    > This doesn't copy everything. But perhaps you know that and you're just
    > testing us.
    >
    >> expr=compile(input('statements assigning to some local variables '),
    >> 'user input','exec')
    >> exec(expr,globals(),_locals)
    >>
    >> How can I "copy" the new values within _locals to my current locals.
    >>
    >> If I knew that Var1 has changed I could say
    >> Var1 = _locals['Var1'] but what to do in general?

    >
    > locals()["Var1"] = _locals["Var1"] will set the same Var1 local.
    >
    > So you might write a loop on _locals.
    >
    > But beware if someone has deleted one of the "variables" it may not do
    > what you'd like. You cannot necessarily add back a local with the above
    > syntax.
    >

    The docs for locals() warns """The contents of this dictionary should
    not be modified; changes may not affect the values of local and free
    variables used by the interpreter."""

    That's because local variables in a function are implemented (at least
    in CPython) using 'slots' for efficiency reasons.

    >>> def example():

    a = 1
    print("a is {}, locals() is {}".format(a, locals()))
    print("Changing a to 2 directly")
    a = 2
    print("a is {}, locals() is {}".format(a, locals()))
    print("Changing a to 3 via locals()")
    locals()["a"] = 3
    print("a is {}, locals() is {}".format(a, locals()))
    locals()["b"] = 0
    print("locals() is {}".format(locals()))
    print("b is {}".format(b))

    >>> example()

    a is 1, locals() is {'a': 1}
    Changing a to 2 directly
    a is 2, locals() is {'a': 2}
    Changing a to 3 via locals()
    a is 2, locals() is {'a': 2}
    locals() is {'b': 0, 'a': 2}
    Traceback (most recent call last):
    File "<pyshell#39>", line 1, in <module>
    example()
    File "<pyshell#38>", line 12, in example
    print("b is {}".format(b))
    NameError: global name 'b' is not defined

    Note how attempting to change variable "a" in locals() is ignored, and
    how adding variable "b" to locals() doesn't actually make it a local
    variable (it raises a NameError).
    MRAB, Feb 12, 2013
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. tedsuzman
    Replies:
    2
    Views:
    7,081
    Michel Claveau, résurectionné d'outre-bombe inform
    Jul 21, 2004
  2. Ted
    Replies:
    1
    Views:
    463
    Duncan Booth
    Jul 22, 2004
  3. Dave Angel
    Replies:
    2
    Views:
    137
    Steven D'Aprano
    Feb 13, 2013
  4. Terry Reedy
    Replies:
    0
    Views:
    127
    Terry Reedy
    Feb 12, 2013
  5. Dave Angel
    Replies:
    0
    Views:
    124
    Dave Angel
    Feb 12, 2013
Loading...

Share This Page