Prev: NotImplemented used in Decimal
Next: Reminder: 6 days left for EuroPython 2010 talk submissions
From: Gary Herron on 24 Apr 2010 12:03 Yingjie Lan wrote: > --- On Sat, 4/24/10, Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au> wrote: > > >> From: Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au> >> Subject: Re: NameError: how to get the name? >> To: python-list(a)python.org >> Date: Saturday, April 24, 2010, 4:07 PM >> On Sat, 24 Apr 2010 04:19:43 -0700, >> 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: >> >> > > I tried this, and it worked: > > Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29) > [GCC 4.2.1 (Apple Inc. build 5646)] on darwin > Type "help", "copyright", "credits" or "license" for more information. > >>>> while True: >>>> > ... try: print a > ... except: locals()['a']="HERE YOU ARE" > ... else: break > ... > HERE YOU ARE > Yes, but as Steven D'Aprano said, this won't work inside a function. Try it. Also if you find an instance where this works, you can't rely on the behavior. If you RTM, you'll find this: locals()¶ <http://docs.python.org/library/functions.html#locals> Update and return a dictionary representing the current local symbol table. Free variables are returned by locals() <http://docs.python.org/library/functions.html#locals> when it is called in function blocks, but not in class blocks. Note: The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter. Gary Herron
From: Yingjie Lan on 24 Apr 2010 19:17 --- On Sat, 4/24/10, Gary Herron <gherron(a)islandtraining.com> wrote: > From: Gary Herron <gherron(a)islandtraining.com> > Subject: Re: NameError: how to get the name? > To: > Cc: python-list(a)python.org > Date: Saturday, April 24, 2010, 8:03 PM > Yingjie Lan wrote: > > --- On Sat, 4/24/10, Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au> > wrote: > > > > > >> From: Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au> > >> Subject: Re: NameError: how to get the name? > >> To: python-list(a)python.org > >> Date: Saturday, April 24, 2010, 4:07 PM > >> On Sat, 24 Apr 2010 04:19:43 -0700, > >> 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: ============================================ def wrapfun(): while True: try: print a except: globals()['a']="HERE YOU ARE" else: break finally: print globals()['a'] wrapfun() ============================================ Thanks for the information! BTW, why would locals() and globals() differ in this respect? For example: ============================================ def wrapfun(): while True: try: print a except: locals()['a']="HERE YOU ARE" else: break finally: print locals()['a'] wrapfun() ============================================ That would print "HERE YOU ARE" infinitely. Apparently, the dict gets modified, but is not the same as the one actually used to resolve name 'a' in the statement 'print a'. Yingjie
From: Chris Rebert on 24 Apr 2010 19:27 On Sat, Apr 24, 2010 at 4:17 PM, Yingjie Lan <lanyjie(a)yahoo.com> wrote: > --- On Sat, 4/24/10, Gary Herron <gherron(a)islandtraining.com> wrote: >> From: Gary Herron <gherron(a)islandtraining.com> >> Date: Saturday, April 24, 2010, 8:03 PM >> Yingjie Lan wrote: >> > --- On Sat, 4/24/10, Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au> >> wrote: >> >> From: Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au> >> >> Subject: Re: NameError: how to get the name? >> >> To: python-list(a)python.org >> >> Date: Saturday, April 24, 2010, 4:07 PM >> >> On Sat, 24 Apr 2010 04:19:43 -0700, >> >> 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). Cheers, Chris -- http://blog.rebertia.com
From: Yingjie Lan on 25 Apr 2010 01:07 --- On Sun, 4/25/10, Chris Rebert <clp2(a)rebertia.com> wrote: > From: Chris Rebert <clp2(a)rebertia.com> > Subject: Re: NameError: how to get the name? > To: "Yingjie Lan" <lanyjie(a)yahoo.com> > Cc: python-list(a)python.org > Date: Sunday, April 25, 2010, 3:27 AM > On Sat, Apr 24, 2010 at 4:17 PM, > Yingjie Lan <lanyjie(a)yahoo.com> > wrote: > > --- On Sat, 4/24/10, Gary Herron <gherron(a)islandtraining.com> > wrote: > >> From: Gary Herron <gherron(a)islandtraining.com> > >> Date: Saturday, April 24, 2010, 8:03 PM > >> Yingjie Lan wrote: > >> > --- On Sat, 4/24/10, Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au> > >> wrote: > >> >> From: Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au> > >> >> Subject: Re: NameError: how to get the > name? > >> >> To: python-list(a)python.org > >> >> Date: Saturday, April 24, 2010, 4:07 PM > >> >> On Sat, 24 Apr 2010 04:19:43 -0700, > >> >> 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? Yingjie
From: Chris Rebert on 25 Apr 2010 02:09 On Sat, Apr 24, 2010, Yingjie Lan <lanyjie(a)yahoo.com> wrote: > On Sun, 4/25/10, Chris Rebert <clp2(a)rebertia.com> wrote: >> On Sat, Apr 24, 2010, Yingjie Lan <lanyjie(a)yahoo.com> wrote: >> > On Sat, 4/24/10, Gary Herron <gherron(a)islandtraining.com> wrote: >> >> Yingjie Lan wrote: >> >> > On Sat, 4/24/10, Steven D'Aprano <steve@--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
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: NotImplemented used in Decimal Next: Reminder: 6 days left for EuroPython 2010 talk submissions |