Descriptors and decorators
bruno.desthuilliers at gmail.com
bruno.desthuilliers at gmail.com
Mon Oct 25 09:20:35 EDT 2010
On 25 oct, 14:15, Joost Molenaar <j.j.molen... at gmail.com> wrote:
> WebOb contains this little nugget of code that allows you to define a
> decorator that works on both methods and functions:
>
> class Decorator(object):
> def __init__(self, func):
> self.func = func
> def __get__(self, object, type=None):
> if type is None:
> return self
> newfunc = self.func.__get__(object, type)
> return self.__class__(newfunc)
(snip)
> I'm still not sure what Decorator.__get__ does, or at least I'm not
> sure enough to be able to explain it well.
http://wiki.python.org/moin/FromFunctionToMethod
> Logically, the method C.m is unbound at the time the class is defined
"At the time the class is defined" - that is (usually) when the
"class" statement's body is executed -, 'm' is a plain function. Note
that by that time, class 'C' doesn't even exist, so there's no way you
could have a 'C.m' method ;)
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.
HTH
More information about the Python-list
mailing list