Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.xs4all.nl!newsfeed3a.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!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.001 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'subject:error': 0.03; 'resulting': 0.04; 'interpreter': 0.05; 'attribute': 0.07; 'context': 0.07; 'variables': 0.07; 'imported': 0.09; 'namespace': 0.09; 'stack.': 0.09; 'python': 0.11; 'def': 0.12; 'jan': 0.12; '24,': 0.16; 'bind': 0.16; 'globals': 0.16; 'objects.': 0.16; 'says...': 0.16; 'pushed': 0.16; 'sat,': 0.16; 'wrote:': 0.18; 'looked': 0.18; 'variable': 0.18; 'module': 0.19; '>>>': 0.22; 'import': 0.22; 'load': 0.23; 'byte': 0.24; 'question': 0.24; 'this:': 0.26; 'header:In-Reply-To:1': 0.27; 'correct': 0.29; "doesn't": 0.30; 'reaches': 0.30; 'statement': 0.30; 'message- id:@mail.gmail.com': 0.30; "i'm": 0.30; 'code': 0.31; "skip:' 10": 0.31; 'object.': 0.31; 'says': 0.33; 'skip:d 20': 0.34; 'knowledge': 0.35; 'no,': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'add': 0.35; 'there': 0.35; 'really': 0.36; 'so,': 0.37; 'being': 0.38; 'whatever': 0.38; 'to:addr :python-list': 0.38; 'pm,': 0.38; 'expect': 0.39; 'does': 0.39; 'to:addr:python.org': 0.39; 'how': 0.40; 'above,': 0.60; "you're": 0.61; 'name': 0.63; 'map': 0.64; 'article': 0.77; '2015': 0.84; 'dict,': 0.84; 'imagine': 0.93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type; bh=aW0huPQIieZw2lkAbFwMCnoOMahu10uq8ranP2N/Pw0=; b=mECwTzqiVkaN4AEE5UKXXJ/Lb6YiKd0NCKaJx0R2WvVuSKlxO/Xlm302HugKVCEyqP mPiNXd62GQxAMMbpPh4UFkjhdwKENdtUwpgiJKr3YjuthW8MZFEYspwKegFGSmwFf0xr uBesJyzLGefXwuE56I6w7u2rVCuAAx0A2pbfrelneMyENELCIvcQA0kA3Pvj6dUlruvd YiYKoBn216zqEqMtWa6OzfN4CWuhk0iriBkh1x4uWW6vvgbVOll0pRK1rBN8Rd7YJCZi uI3qSgTMoF+nJQhVzqnOGwu5Y99gYvpKcHZ5uFKCX7EXuqC1NlvRO9LPB/OBWdpd8bsw 5DhQ== X-Received: by 10.66.174.165 with SMTP id bt5mr22543481pac.53.1422137846190; Sat, 24 Jan 2015 14:17:26 -0800 (PST) MIME-Version: 1.0 In-Reply-To: References: <1a194e0a0b738d205de54180fa7@nntp.aioe.org> <54c39366$0$13006$c3e8da3$5496439d@news.astraweb.com> From: Ian Kelly Date: Sat, 24 Jan 2015 15:16:45 -0700 Subject: Re: __bases__ misleading error message To: Python Content-Type: text/plain; charset=UTF-8 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 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: 56 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1422137849 news.xs4all.nl 2886 [2001:888:2000:d::a6]:49778 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:84504 On Sat, Jan 24, 2015 at 3:02 PM, Mario Figueiredo wrote: > In article , > tjreedy@udel.edu says... >> >> > "__main__" >> > from module import a_name >> >> A module is a namespace associating names with objects. This statememt >> says to import the a_name to object association from module and add it >> to __main__ >> >> > y = a_name + 1 >> >> This statement uses the imported association in __main__ to access the >> object and add 1, and bind 'y' to the resulting object. > > > But I'm being told the interpreter has no knowledge of a variable name. > So, how does the interpreter know, once it reaches the assigment line > above, how to map a_name to the correct object in memory? No, you're being told that the *object* doesn't know the names of the variables that it's bound to. In the context above, the variable is right there under that name in the globals dict, as can be seen in the disassembly: >>> import dis >>> dis.dis("y = a_name + 1") 1 0 LOAD_NAME 0 (a_name) 3 LOAD_CONST 0 (1) 6 BINARY_ADD 7 STORE_NAME 1 (y) 10 LOAD_CONST 1 (None) 13 RETURN_VALUE Now what happens in the byte code if we try to access an attribute on that object? >>> dis.dis("a_name.__bases__") 1 0 LOAD_NAME 0 (a_name) 3 LOAD_ATTR 1 (__bases__) 6 RETURN_VALUE 1) The value of a_name is looked up and pushed onto the stack. 2) The interpreter attempts to load the attribute __bases__ of whatever object is on the top of the stack. There is no name associated with that object at this point; it's just an object. Now imagine if the Python code in question were instead this: def get_an_object(): return "foo" get_an_object().__bases__ Would you really expect the interpreter to come up with a message like "Return value of get_an_object() has no attribute '__bases__'"?