On Sat, Apr 24, 2010, Yingjie Lan <lany...@yahoo.com> wrote: > On Sun, 4/25/10, Chris Rebert <c...@rebertia.com> wrote: >> On Sat, Apr 24, 2010, Yingjie Lan <lany...@yahoo.com> wrote: >> > On Sat, 4/24/10, Gary Herron <gher...@islandtraining.com> wrote: >> >> Yingjie Lan wrote: >> >> > On Sat, 4/24/10, Steven D'Aprano <st...@--cybersource.com.au> wrote: >> >> >> On Sat, 24 Apr 2010, Yingjie Lan wrote: >> >> >>> I wanted to do something like this: >> >> >>> >> >> >>> while True: >> >> >>> try: >> >> >>> def fun(a, b=b, c=c): >> >> pass >> >> >>> except NameError as ne: >> >> >>> name = >> >> get_the_var_name(ne) >> >> >>> locals()[name] = '' >> >> >>> else: break >> >> >>> >> >> >> This won't work. Writing to locals() does >> not >> >> actually >> >> >> change the local variables. Try it inside >> a >> >> function, and you will see it >> >> >> doesn't work: >> > >> > No it DOESN'T work, and both of you are precisely >> correct. >> > Just for playing around, I substituted >> > "locals()" by "globals()" and it worked as desired: >> <snip> >> > Thanks for the information! BTW, why would >> > locals() and globals() differ in this respect? >> >> The module-level (i.e. global) namespace is implemented by >> CPython >> using an actual dictionary; globals() returns a proxy to >> that >> dictionary and lets you manipulate it. >> In contrast, as an optimization, CPython implements local >> variables in >> functions using predetermined offsets into an array of >> predetermined >> length; the dictionary returned by locals() is dynamically >> constructed >> on-demand and does not affect the actual array used for the >> local >> variables (I suppose it could have been made to do so, but >> there's >> probably a complexity or optimization reason for why not). >> > > Thanks, that's good to know. The locals() behaves rather > strangely, as can be demonstrated by the following two > tests (the first one is from Steven, thanks Steve): > > #file: fun.py: > > def test(): > x = 1 > print (x) > locals()['x'] = 2 > print (x, locals()['x']) > > def test2(): > locals()['x'] = 2 > print (locals()['x']) > print x > > test() > test2() > > -----And the output: python fun.py------- > 1 > (1, 1) > 2 > Traceback (most recent call last): > File "fun.py", line 21, in <module> > test2() > File "fun.py", line 17, in test2 > print x > NameError: global name 'x' is not defined > > ------------- > > I don't know how to make sense out of it. > Any suggestions?
My working theory is that attempting to modify a key in locals() corresponding to an extant variable has no effect, even on just the locals() dictionary itself, and is ignored, but adding or modifying other keys in locals() works like a normal dictionary. def test3(): x = 1 print x locals()['x'] = 2 locals()['y'] = 3 print x, locals()['x'], locals()['y'] print y $ python test3.py 1 1 1 3 Traceback (most recent call last): File "Desktop/tmp.py", line 22, in <module> test3() File "Desktop/tmp.py", line 7, in test3 print y NameError: global name 'y' is not defined As for why you get a NameError in test2() [assuming that's part of what's confusing you], there's no assignment to `x` in test2(), so Python reasons you must be referring to a global variable `x`. But there is no such global variable, hence the NameError. Cheers, Chris -- Your mail client's quoting style is a bit annoying. http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list