Path: csiph.com!x330-a1.tempe.blueboxinc.net!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!de-l.enfer-du-nord.net!feeder1.enfer-du-nord.net!feeds.phibee-telecom.net!newsfeed.xs4all.nl!newsfeed5.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; '(although': 0.05; 'exec': 0.07; 'symbols': 0.07; 'python': 0.08; '>>>>': 0.09; 'dict': 0.09; 'executes': 0.09; 'match.': 0.09; 'nameerror:': 0.09; 'nicely': 0.09; 'error:': 0.10; 'am,': 0.12; 'def': 0.13; "hasn't": 0.13; 'why.': 0.15; 'cc:addr:python-list': 0.15; 'received:74.125.82.44': 0.15; 'received:mail-ww0-f44.google.com': 0.15; 'syntax': 0.15; '"copyright",': 0.16; '"credits"': 0.16; '"license"': 0.16; "'a'": 0.16; '[gcc': 0.16; 'compiler,': 0.16; 'dictionary,': 0.16; 'disables': 0.16; 'frame,': 0.16; 'linux2': 0.16; 'syntaxerror:': 0.16; 'wrote:': 0.16; 'wed,': 0.17; '>>>': 0.18; 'subject:Question': 0.19; 'cheers,': 0.20; '(most': 0.21; 'cc:no real name:2**0': 0.21; "doesn't": 0.22; 'feb': 0.22; 'header:In-Reply-To:1': 0.22; 'figure': 0.23; 'statement': 0.23; 'assigning': 0.23; 'defined': 0.24; 'fine': 0.24; 'stack': 0.24; 'traceback': 0.24; 'cc:2**0': 0.25; 'guess': 0.25; 'function': 0.27; 'variable': 0.27; 'message-id:@mail.gmail.com': 0.28; 'example': 0.28; 'problem': 0.29; 'print': 0.29; 'cc:addr:python.org': 0.29; 'second': 0.29; 'operation.': 0.30; 'actual': 0.32; "can't": 0.32; 'setting': 0.34; "we're": 0.34; 'function.': 0.34; 'last):': 0.34; 'nested': 0.34; 'received:74.125.82': 0.34; 'probably': 0.35; '...': 0.35; 'file': 0.35; 'presence': 0.36; 'variables': 0.36; 'but': 0.37; 'received:74.125': 0.37; 'received:google.com': 0.37; 'another': 0.37; 'happens': 0.37; 'should': 0.38; 'returned': 0.38; 'subject:: ': 0.39; 'type': 0.60; 'more': 0.61; 'your': 0.61; 'course,': 0.61; 'free': 0.63; 'believe': 0.65; 'subject:name': 0.67; 'works,': 0.68; 'hand,': 0.76; '11:47': 0.84; 'compare:': 0.84; 'compiles': 0.84; 'locals': 0.84; 'subject,': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type:content-transfer-encoding; bh=gUB9VoEGR+mpz95+0ZPfsyawKyzNmbc9JL4jEW6HbPo=; b=lYSOa3QwGwH5cu3+DvQ3fbf1mw3SPqj9q853thMz70EzSA8Vyk2qPXUC2NTNaYKVy9 W5XcOS7ljr1lm5t1Y1P3QmELo+5EJK58IbacVqffswfliUDlFByr24r9LyMiJEYVJlYZ PDePTi3vlO7+lvCNpkO+HIxi4K/2xUIGclHko= MIME-Version: 1.0 In-Reply-To: References: <20120201181117.5d35dddc@bigfoot.com> From: Ian Kelly Date: Wed, 1 Feb 2012 14:49:52 -0700 Subject: Re: Question about name scope To: mwilson@the-wire.com Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Cc: python-list@python.org X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 75 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1328133024 news.xs4all.nl 6896 [2001:888:2000:d::a6]:41642 X-Complaints-To: abuse@xs4all.nl Xref: x330-a1.tempe.blueboxinc.net comp.lang.python:19744 On Wed, Feb 1, 2012 at 11:47 AM, Mel Wilson wrote: > I guess they want local symbols in functions to be pre-compiled. =A0Simil= ar to > the way you can't usefully update the dict returned by locals(). =A0Stran= gely, > I notice that > > Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) > [GCC 4.4.3] on linux2 > Type "help", "copyright", "credits" or "license" for more information. >>>> def f(x): > ... =A0 exec x > ... =A0 exec 'print a' > ... >>>> f('a=3D4') > 4 >>>> > > works, but I really cannot explain why. I am not a dev, but I believe it works because assigning to locals() and assigning via exec are not the same thing. The problem with assigning to locals() is that you're fundamentally just setting a value in a dictionary, and even though it happens to be the locals dict for the stack frame, Python can't figure out that it should go and update the value of the optimized local to match. exec, on the other hand, compiles and executes an actual STORE_NAME operation. Of course, if the particular local variable hasn't been optimized by the compiler, then updating locals() works just fine (although you probably should not rely on this): >>> def f(x, y): ... locals()[x] =3D y ... print locals()[x] ... exec 'print ' + x ... >>> f('a', 42) 42 42 Another interesting thing to note is that the print in your example doesn't even need to be in a second exec, which I believe works because the presence of any exec statement disables global variable optimizations for the function. Compare: >>> def f(x): ... locals()['a'] =3D 4 ... print a ... >>> f('pass') Traceback (most recent call last): File "", line 1, in File "", line 3, in f NameError: global name 'a' is not defined >>> def f(x): ... locals()['a'] =3D 4 ... print a ... exec x ... >>> f('pass') 4 And while we're on the subject, here's a nicely obscure syntax error: >>> def f(x): ... def g(): ... print x ... exec x ... File "", line 4 SyntaxError: unqualified exec is not allowed in function 'f' it contains a nested function with free variables Cheers, Ian