Devin Jeanpierre wrote: > -- Devin > > On Sun, Feb 1, 2015 at 11:15 PM, Steven D'Aprano > <steve+comp.lang.pyt...@pearwood.info> wrote: >> Gregory Ewing wrote: >> >>> Steven D'Aprano wrote: >>>> [quote] >>>> If the object has a method named __dir__(), this method will >>>> be called and must return the list of attributes. >>>> [end quote] >>>> >>>> The first inaccuracy is that like all (nearly all?) dunder methods, >>>> Python only looks for __dir__ on the class, not the instance itself. >>> >>> It says "method", not "attribute", so technically >>> it's correct. The methods of an object are defined >>> by what's in its class. >> >> Citation please. I'd like to see where that is defined. > > https://docs.python.org/3/glossary.html#term-method
Run this code using any version of Python from 1.5 onwards, and you will see that the definition is wrong: # === cut === class K: def f(self): pass # Define a function OUTSIDE of a class body. def g(self): pass K.g = g instance = K() assert type(instance.f) is type(instance.g) print(type(instance.f)) print(type(instance.g)) # === cut === Both K.f and K.g are methods, even though only one meets the definition given in the glossary. The glossary is wrong. Or rather, it is not so much that it is *wrong*, but that it is incomplete and over-simplified. It describes how methods are normally (but not always) defined, but not what they are. It is rather like defining "coffee" as the milky drink you buy from Starbucks, then insisting that the black liquid that you drank in an Italian restaurant cannot be coffee because you didn't buy it from Starbucks. Glossary entries are typically simplified, not exhaustive. It is not wise to take a three line glossary entry as a complete, definite explanation. In this case the glossary fails to tell you that methods are not *required* to be defined inside a class body, that is merely the usual way to do it. >> Even if it is so defined, the definition is wrong. You can define methods >> on an instance. I showed an example of an instance with its own personal >> __dir__ method, and showed that dir() ignores it if the instance belongs >> to a new-style class but uses it if it is an old-style class. > > You didn't define a method, you defined a callable attribute. That is wrong. I defined a method: py> from types import MethodType py> type(instance.f) is MethodType True 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. I could also call the descriptor __get__ method by hand, if you prefer: py> def h(self): pass ... py> method = h.__get__(K, instance) py> assert type(method) is type(instance.f) py> print(method) <bound method type.h of <class '__main__.K'>> -- Steven -- https://mail.python.org/mailman/listinfo/python-list