Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!goblin1!goblin2!goblin.stu.neva.ru!newsfeed.xs4all.nl!newsfeed2a.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; 'argument': 0.05; 'class,': 0.07; 'method.': 0.07; '*is*': 0.09; 'explanation': 0.09; 'function,': 0.09; 'instances.': 0.09; 'method,': 0.09; 'subject:instance': 0.09; 'cc:addr:python-list': 0.11; 'def': 0.12; 'doing:': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'happily': 0.16; 'magic': 0.16; 'subject:class': 0.16; 'subject:variable': 0.16; 'unbound': 0.16; 'weird': 0.16; 'wrote:': 0.18; 'wed,': 0.18; 'work,': 0.20; '>>>': 0.22; 'aug': 0.22; 'cc:addr:python.org': 0.22; 'body,': 0.24; 'instance,': 0.24; 'please?': 0.24; 'skip': 0.24; 'cc:2**0': 0.24; "i've": 0.25; 'define': 0.26; 'pass': 0.26; 'header:In-Reply-To:1': 0.27; 'tried': 0.27; 'function': 0.29; 'message-id:@mail.gmail.com': 0.30; "i'm": 0.30; '(which': 0.31; '13,': 0.31; 'directly,': 0.31; 'piece': 0.31; 'class': 0.32; 'regular': 0.32; 'subject:from': 0.34; 'could': 0.34; "can't": 0.35; 'something': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'there': 0.35; 'doing': 0.36; 'method': 0.36; "i'll": 0.36; 'two': 0.37; 'pm,': 0.38; 'track': 0.38; 'rather': 0.38; 'little': 0.38; 'though,': 0.39; 'called': 0.40; "you're": 0.61; 'first': 0.61; 'back': 0.62; "you'll": 0.62; 'name': 0.63; 'kind': 0.63; 'provide': 0.64; 'details': 0.65; 'to:none': 0.92 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=VY91WJSczuG6GbgN7RoX5y26LFRBOMRjwy/GTHftYYw=; b=iimwBOkHVhITrD/fdMY0qf827S0LhfbAFS7rPswm+4IFyhU/1At2iz5zRBZhR2xnwV p5+mMJAOLkvT04f3sXkoUeW5LPzz9jFoFKkh+OeAXbDK70yBbMoe6h74eiO2ifVogyJN N4kZ8VW9lKEqYPAGGVLXBKae4pc1+US2JckmGaLF6hSgZHHHAW0fo3fNCEyYt1a5PprK wJIx1TT8FBtSWlmeDCUNBSao80nPck9Iz+jrBeCYlD4najZP8s8UefYljgHXmzMjdTXA +ROJ7VClK4qQvlOduIecHneXBNqkzaulmD28iYnecsnsn52DuDpaPrQboBJGK3rvkJZO 1Ocg== MIME-Version: 1.0 X-Received: by 10.50.66.197 with SMTP id h5mr47903614igt.34.1407923105591; Wed, 13 Aug 2014 02:45:05 -0700 (PDT) In-Reply-To: <201408131006549222-not@myrealaddresscom> References: <201408131006549222-not@myrealaddresscom> Date: Wed, 13 Aug 2014 19:45:05 +1000 Subject: Re: odd difference calling function from class or instance variable From: Chris Angelico Cc: "python-list@python.org" 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: 42 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1407923108 news.xs4all.nl 2841 [2001:888:2000:d::a6]:56239 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:76180 On Wed, Aug 13, 2014 at 7:06 PM, GregS wrote: > If you look at i.ref.__self__ for the two cases, you'll see what's going on. > I've tried RTFMing but can't find the reason for the two behaviours. Could > someone provide an explanation for me, please? What you're seeing there is the magic of instance methods. I'll simplify it some by defining the method right there in the class, rather than doing the weird injection that you were doing: >>> class C: def meth(self): print("Hi! I'm a method.",self) >>> C().meth() Hi! I'm a method. <__main__.C object at 0x012BC6D0> >>> C.meth >>> C().meth > >>> _() Hi! I'm a method. <__main__.C object at 0x012AEDF0> When you look up something on the instance, if there's a regular function of that name on its class, you'll get back a piece of magic called a bound method. It's a curried function, if you know what that means (if you don't, just skip this sentence). When you then call that bound method, it ultimately goes back to the original function, with a pre-filled first argument (which comes from __self__). Basically, what this means is that a bound method can be treated like a function, and it automatically keeps track of its proper state; the unbound method *is* a function, so if you call that directly, you'll need to pass it an object as self. >>> C.meth(C()) Hi! I'm a method. <__main__.C object at 0x0169AA70> As a general rule, though, you won't be doing this kind of thing. Define functions inside a class body, and then call them on instances. Everything'll happily work, and all these little details are magic :) ChrisA