__metaclass__ and __author__ are already decorators

Paul Morrow pm_mon at yahoo.com
Sat Aug 21 16:38:01 CEST 2004


Thinking about decorators, and looking at what we are already doing in 
our Python code, it seems that __metaclass__, __author__, __version__, 
etc. are all examples of decorators.  So we already have a decorator 
syntax.  What is the compelling reason to invent a new one?  And if we 
do, what's to become of the old one?

Here's my take on this.  We have two kinds of decorators:  those that 
are informational only (like __author__ and __version__), and those 
which have side-effects, i.e. those that actually *do* something (like 
__metaclass__).

     class Foo:
         """ This describes the Foo class as normal. """
         __metaclass__ = M
         __author__ = 'Paul Morrow'
         __version__ = '0.1'
         __automethods__ = True


         def baz(self, a, b):
             """ This describes the baz method. """
             __synchronized__ = True
             __returns__ = None
             __author__ = 'Neville Shunt'
             # body of baz goes here...

There, that looks pretty clear and pythonic.  Now how to define the 
decorators.

     def metaclass(decoratedClass, subType):
         """ This describes the 'metaclass' decorator. """
         __decorator__ = True
         __version__ = '1.9'
         # perform the metaclass operation on decoratedClass


     def synchronized(decoratedFunc, trueOrFalse):
         """ This describes the 'synchronized' decorator. """
         __decorator__ = True
         __author__ = 'Martin Curry'
         __version__ = '0.5'
         # perform the synchronized operation on decoratedClass


     def returns(decoratedFunc, *args):
         """Docstring for 'returns' decorator."""
         __decorator__ = True
         # body of decorator goes here


Each decorator function receives the class|function|method being 
decorated as the first parameter of the function (e.g. decoratedClass 
and decoratedFunc above).  The remaining parameters are the values 
assigned to the __xxx__ variable in the definition of the decorated 
function.

So, in the above example, when the 'returns' decorator function is 
called to decorate the 'baz' method, decoratedFunc would recieve the baz 
object and args[0] would be set to None (because of the statement 
"__returns__ = None" in the definition of baz).

For a function to be used as a decorator function, it must be decorated 
as such, by setting its __decorator__ attribute to True.

Does this handle enough of the decorator concerns?

Paul




More information about the Python-list mailing list