Devin Jeanpierre wrote: > On Mon, Feb 2, 2015 at 4:06 AM, Steven D'Aprano > <steve+comp.lang.pyt...@pearwood.info> wrote:
>> instance.f is a method by the glossary definition. Its type is identical >> to types.MethodType, which is what I used to create a method by hand. > > You are assuming that they are both methods, just because they are > instances of a type called "MethodType". This is like assuming that a > Tree() object is made out of wood. No. It is "assuming" that a Tree() object is a Tree() object. 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. 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. > The documentation is free to define things in terms other than types > and be correct. If you wanted to argue that "method" is a generic term, and we have instance methods, class methods, static methods, and any other sort of method we care to create using the descriptor protocol, then I would agree you have a point. But since we're just talking about instance methods, Python doesn't care how they came into existence. You can use def to create a function inside a class body, inject a function into the class, call the descriptor __get__ method, or use the types.MethodType type object, it is all the same. You can use a def statement, or a lambda, or types.FunctionType if you are really keen. It makes no difference. Do I expect the glossary to go into such pedantic detail? No, of course not. But I do expect anyone with a few years of Python programming experience to be able to understand that what makes a method be a method is its type and behaviour, not where it came from. > There are many properties of functions-on-classes that > callable instance attributes that are instances of MethodType do not > have, as we've already noticed. isinstance can say one thing, and the > documentation another, and both can be right, because they are saying > different things. > > > 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! <bound method Q.f of <__main__.Q object at 0xb7b8fcec>> py> MethodType(f, instance) # Uses "inside" f, so is a real method! <bound method Q.f of <__main__.Q object at 0xb7b8fcec>> -- Steven -- https://mail.python.org/mailman/listinfo/python-list