On Fri, 7 Oct 2016 04:01 pm, ast wrote: > > "Gregory Ewing" <greg.ew...@canterbury.ac.nz> a écrit dans le message de > news:e5mgi9fp1b...@mid.individual.net... >> Lawrence D’Oliveiro wrote: >>> >>> Every function is already a descriptor. >> >> Which you can see with a simple experiment: >> >> >>> def f(self): >> ... print("self =", self) >> ... > > I thought yesterday that every thing was clear. But I have > a doubt now with the following line: > >> >>> g = f.__get__(17, None) > > The signature of __get__ method is __get__ (self, inst, owner) so > once again the first parameter is filled automatically. > Is method __get__ itself a descriptor with an attribute __get__ to perform > the operation ? Hum, it would be endless ...
No it is not: py> def f(): pass ... py> hasattr(f.__get__, '__get__') False So what kind of thing is f.__get__? f itself is a function, which looks like this: py> f <function f at 0xb7b83fa4> but f.__get__ is something different: py> f.__get__ <method-wrapper '__get__' of function object at 0xb7b83fa4> "Method-wrapper" is an undocumented internal implementation detail. It isn't part of the Python language, just part of the runtime implementation. If we use Jython instead, we see something different: steve@orac:~$ jython Jython 2.5.1+ (Release_2_5_1, Aug 4 2010, 07:18:19) [OpenJDK Server VM (Sun Microsystems Inc.)] on java1.6.0_31 Type "help", "copyright", "credits" or "license" for more information. >>> def f(): pass ... >>> f <function f at 0x1> >>> f.__get__ <built-in method __get__ of function object at 0x1> So the Python language doesn't make any promises about what sort of thing __get__ will be, only that it exists and is callable. Anything I say here is an implementation detail: it may change in the future, it may have already changed, and different Python implementations may do things differently. Back to CPython: f.__get__ is a method-wrapper. That gives us a hint that although __get__ itself isn't a descriptor, it is a thing returned by something which is a descriptor. Remember that all functions are instances of a built-in class, FunctionType: py> from types import FunctionType py> assert type(f) is FunctionType py> vars(FunctionType)['__get__'] <slot wrapper '__get__' of 'function' objects> It is *that* "slot wrapper" thing which is itself a descriptor: py> vars(FunctionType)['__get__'].__get__ <method-wrapper '__get__' of wrapper_descriptor object at 0xb7cf2504> and it returns f.__get__: py> vars(FunctionType)['__get__'].__get__(f) <method-wrapper '__get__' of function object at 0xb7b83fa4> which returns a method: py> class X(object): pass ... py> x = X() py> vars(FunctionType)['__get__'].__get__(f)(x, X) <bound method X.f of <__main__.X object at 0xb7b0a92c>> -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list