[Python-Dev] order of decorator application?

Phillip J. Eby pje at telecommunity.com
Tue Mar 23 11:42:29 EST 2004


At 10:24 AM 3/23/04 -0600, Skip Montanaro wrote:

>(I'm working on PEP 318...)
>
>Is there a concensus on the order of application for decorators?  Should
>
>     def func(a,b) [d1,d2]:
>         pass
>
>be equivalent to
>
>     def func(a,b):
>         pass
>     func = d1(d2(func))

No.


>or
>
>     def func(a,b):
>         pass
>     func = d2(d1(func))

Almost.  :)  Try this phrasing, which provides its own justification for 
the interpretation:

def func(a,b):
     pass

for decorator in [d1,d2]:
     func = decorator(func)


This is still "almost", because 'func' should only be bound *once*, at the 
conclusion of the operation.  IOW, more like:

def _temp(a,b):
     pass

_temp.__name__ = "func"

for decorator in [d1,d2]:
     _temp = decorator(_temp)

func = _temp

In practice, the compiler can and should unroll the loop, keep the 
intermediate values on the stack, and have the right function name assigned 
from the start.  But the specification *should* require that 'func' not be 
rebound until the operation is concluded.  This allows multi-function 
objects to be accumulated, such as for properties, generic functions, and 
so on, without losing the "previous" definition.  For example, I should be 
able to do something like:

    def some_attr(self) [getter]:
        ...

    def some_attr(self,value) [setter]:
        ...

And have the first 'some_attr' value in effect when 'setter()' is called on 
the second 'some_attr'.  This is also important for creating generic 
functions, or doing signature overloading for interfacing with languages 
like C++ or Java.




More information about the Python-Dev mailing list