Descriptors and decorators

Joost Molenaar j.j.molenaar at gmail.com
Mon Oct 25 17:18:36 CEST 2010


On 25 October 2010 15:20, bruno.desthuilliers at gmail.com
<bruno.desthuilliers at gmail.com> wrote:
> So, your decorator is applied to a function, and wraps it into a
> Decorator object. Or more exactly, the function is defined, then the
> Decorator class is called so a new Decorator object is instanciated
> with the function as argument, and finally this Decorator instance is
> rebound to the name under which the function was formely known. All
> this happenning _before_ class C even exists, so when the class object
> is created, it has an attribute by the name of the decorated function
> which is in fact a Decorator instance.
>
> Now this instance is itself a descriptor, so when C.m or o.m are
> looked up, the descriptor protocol is fired and Descriptor.__get__ is
> called. If called without at least a 'type' argument, it just returns
> itself, so it works as an ordinary function. Else it calls the
> function's own descriptor implementation to get a bound or unbound
> method, and returns a new instance of the decorator with the method as
> argument.

Thanks, Bruno.
Your python-wiki page and walk-through for the Decorator code make it
clear. I now finally understand that methods are in fact ordinary
functions at the time the class is created, and that the descriptor
protocol turns them into bound or unbound methods when they're
accessed as attributes:

>>> class K(object): pass
...
>>> def g(self): pass
...
>>> g
<function g at 0x7f322f701838>
>>> K.m = g
>>> K.m
<unbound method K.g>
>>> K.__dict__['m']
<function g at 0x7f322f701838>
>>> K().m
<bound method K.g of <__main__.K object at 0x7f322f709a50>>

Cheers! Now I will try to wrap my brain around metaclasses and coroutines. ;-)



More information about the Python-list mailing list