Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!feeds.phibee-telecom.net!newsfeed.xs4all.nl!newsfeed2a.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.002 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'retrieved': 0.05; 'subject:Python': 0.06; 'class,': 0.07; 'over,': 0.07; '===': 0.09; 'meaningful': 0.09; 'method,': 0.09; 'protocols.': 0.09; 'runtime': 0.09; 'term,': 0.09; 'things,': 0.09; 'type,': 0.09; 'cc:addr:python-list': 0.11; 'def': 0.12; 'random': 0.14; '(object': 0.16; 'callable': 0.16; 'created.': 0.16; 'defined,': 0.16; 'iterable:': 0.16; 'iterated': 0.16; 'k(object):': 0.16; 'none.': 0.16; 'obviously,': 0.16; 'semantics': 0.16; 'surprises': 0.16; 'to:addr:pearwood.info': 0.16; 'to:addr:steve+comp.lang.python': 0.16; "to:name:steven d'aprano": 0.16; 'two,': 0.16; 'two.': 0.16; 'wrote:': 0.18; 'not,': 0.20; 'feb': 0.22; 'example': 0.22; 'import': 0.22; 'cc:addr:python.org': 0.22; 'refers': 0.24; 'mon,': 0.24; 'cc:2**0': 0.24; 'sort': 0.25; 'pass': 0.26; 'code:': 0.26; 'certain': 0.27; 'defined': 0.27; 'header:In-Reply-To:1': 0.27; 'function': 0.29; 'correct': 0.29; 'on,': 0.29; 'am,': 0.29; 'message-id:@mail.gmail.com': 0.30; 'argue': 0.31; 'claiming': 0.31; "d'aprano": 0.31; 'existence': 0.31; 'reduced': 0.31; 'steven': 0.31; 'class': 0.32; 'run': 0.32; 'url:python': 0.33; '(e.g.': 0.33; 'not.': 0.33; 'skip:_ 10': 0.34; 'subject: (': 0.35; 'agree': 0.35; 'created': 0.35; 'something': 0.35; 'case,': 0.35; 'objects': 0.35; 'point.': 0.35; 'test': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'there': 0.35; 'really': 0.36; 'doing': 0.36; 'method': 0.36; 'url:org': 0.36; 'two': 0.37; 'depends': 0.38; 'generic': 0.38; 'functional': 0.39; 'either': 0.39; 'called': 0.40; 'even': 0.60; 'above,': 0.60; 'tell': 0.60; 'challenge': 0.61; "you're": 0.61; 'save': 0.62; 'term': 0.63; 'real': 0.63; 'different': 0.65; 'due': 0.66; 'between': 0.67; 'believe': 0.68; 'body.': 0.68; 'subject:! ': 0.74; 'cut': 0.74; 'behavior': 0.77; '2015': 0.84; 'avoids': 0.84; 'bodies.': 0.84; 'id,': 0.84; 'subject:!)': 0.84; 'same,': 0.91; 'differences': 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 :cc:content-type; bh=z1X0wnFMAJtXsqyOh6pInua2QfLEj69QbAMtr371ySY=; b=0A+4VRrn5LPmKbokAhrR9/sxDY25Id7NeRr/5A5eTqK+blbt2Sz2vDMX+6+ghigQ+t hK4eCqpFz2QSrQ4OtbJIUbZwG3DJHueh5bxsLUrBsTJSHRJRVF3I+76pHwIMW1peKsOW QpZWb7PwQooDVaUw6DAoTmCREgeNoIy3DnfvfecPCqx5Ki3kea8CnjczBLxKhlABPdH8 olBHKJREXdURIWsp3GzmpMmmmiB+U5B8lSPesw7ReHa2vrThLu7lhqgTJv1ctMmncA4s YcC6+RGBLqzqlIaXWa5E8W44kouaD+wjA0+Zif6JtLcy6OCzMaO0Mzp9+KJEIejVlUbf W7nQ== X-Received: by 10.229.248.138 with SMTP id mg10mr7323812qcb.29.1422955520137; Tue, 03 Feb 2015 01:25:20 -0800 (PST) MIME-Version: 1.0 In-Reply-To: <54cf849d$0$13005$c3e8da3$5496439d@news.astraweb.com> References: <54c07d04$0$13012$c3e8da3$5496439d@news.astraweb.com> <54c83ab4$0$12982$c3e8da3$5496439d@news.astraweb.com> <54ca583e$0$13005$c3e8da3$5496439d@news.astraweb.com> <54ccc2fc$0$13009$c3e8da3$5496439d@news.astraweb.com> <54cd9a7a$0$12984$c3e8da3$5496439d@news.astraweb.com> <54ce526a$0$13012$c3e8da3$5496439d@news.astraweb.com> <54cf242d$0$12991$c3e8da3$5496439d@news.astraweb.com> <54cf6836$0$12996$c3e8da3$5496439d@news.astraweb.com> <54cf849d$0$13005$c3e8da3$5496439d@news.astraweb.com> From: Devin Jeanpierre Date: Tue, 3 Feb 2015 01:24:38 -0800 Subject: Re: dunder-docs (was Python is DOOMED! Again!) To: "Steven D'Aprano" Content-Type: text/plain; charset=UTF-8 Cc: "comp.lang.python" 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: 88 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1422955528 news.xs4all.nl 2970 [2001:888:2000:d::a6]:34839 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:85125 On Mon, Feb 2, 2015 at 6:07 AM, Steven D'Aprano wrote: > Run this code: > > # === cut === > > class K(object): > def f(self): pass > > def f(self): pass > > instance = K() > things = [instance.f, f.__get__(instance, K)] > from random import shuffle > shuffle(things) > print(things) > > # === cut === > > > You allege that one of these things is a method, and the other is not. I > challenge you to find any behavioural or functional difference between the > two. (Object IDs don't count.) > > If you can find any meaningful difference between the two, I will accept > that methods have to be created as functions inside a class body. In this particular case, there is none. What if the body of the "method" was super().f() ? Some methods can be defined outside of the body and still work exactly the same, but others won't. > Otherwise you are reduced to claiming that there is some sort of mystical, > undetectable "essence" or "spirit" that makes one of those two objects a > real method and the other one a fake method, even though they have the same > type, the same behaviour, and there is no test that can tell you which is > which. It isn't mystical. There are differences in semantics of defining methods inside or outside of a class that apply in certain situations (e.g. super(), metaclasses). You have cherrypicked an example that avoids them. If one wants to say "A method can (...) by using super()", then methods must be defined to only exist inside of class bodies. Obviously, once you construct the correct runtime values, behavior might be identical. The difference is in whether you can do different things, not in behavior. >> For an example we can all agree on, this is not an instance of >> collections.Iterable, but the docs claim it is iterable: >> https://docs.python.org/2/glossary.html#term-iterable >> >> class MyIterable(object): >> def __getitem__(self, i): return i > > "Iterable" is a generic term, not a type. Despite the existence of the > collections.Iterable ABC, "iterable" refers to any type which can be > iterated over, using either of two different protocols. > > As I said above, if you wanted to argue that "method" was a general term for > any callable attached to an instance or class, then you might have a point. > But you're doing something much weirder: you are arguing that given two > objects which are *identical* save for their object ID, one might be called > a method, and the other not, due solely to where it was created. Not even > where it was retrieved from, but where it was created. > > If you believe that "method or not" depends on where the function was > defined, then this will really freak you out: > > > py> class Q: > ... def f(self): pass # f defined inside the class > ... > py> def f(self): pass # f defined outside the class > ... > py> f, Q.f = Q.f, f # Swap the "inside" f and the "outside" f. > py> instance = Q() > py> instance.f # Uses "outside" f, so not a real method! > > > py> MethodType(f, instance) # Uses "inside" f, so is a real method! > > You are really missing the point, if you think that surprises me. -- Devin