Are decorators really that different from metaclasses...

Jess Austin jess.austin at gmail.com
Wed Aug 25 20:13:21 EDT 2004


On Tue, 24 Aug 2004 12:29:38 -0400, Paul Morrow <pm_mon at yahoo.com>
wrote:
> 
> No. Function decorators are to functions as class decorators are to classes.
> 
> Class decorators are not in 2.4, because you can do most things you'd
> do with a class decorator by using a metaclass, but in a completely
> different way. In my opinion, class decorators _should_ be in 2.4,
> because they're a much saner way to handle many things that require a
> metaclass today.

So far we agree.

> [snip]  A metaclass allows the user
> to specify an object that builds classes in a new way. A decorator
> allows the user to specify a way to transform the already built
> function (or class, for class decorators).

This is effectively the same thing.  When you call a class object,
whether it is a classic class, new-style class, class with a
metaclass, decorated class, or some legal combination of the
preceding, it returns an object.  You can't have too many expectations
of that object, although typically it will have its __class__ variable
set to the class object you called originally.  Anything a metaclass
can do to the objects it creates (which are typically classes), a
decorator could do to objects (whether functions or classes) it
decorates, if only by creating another object and returning it instead
of the original object.  I'm assuming that the function returned by
the decorator must accept name, bases, dict as arguments just like a
metaclass must.  That returned function will perform in a more
flexible manner since you can also pass arguments to the decorator to
control its behavior - something you couldn't do with a metaclass.  A
factory and a filter are equivalent in the sense that once an object
has squirted out the back end, they don't have access to it anymore.

What differences are there?  There could be a running-time difference,
but who cares about class instantiation time?  Object instantiation
time is what matters.  Also, an object the class of which has
__metaclass__ set currently also has __metaclass__ set to the same
thing.  This seems like an ill-advised feature, through which
presumably you could do odd and unmaintainable things, although these
could also be done through __class__.__metaclass__.  It's also an
inaccurate feature - can a simple object be said to have a metaclass? 
To what would this be set for a class whose metaclass had a metaclass?

Anthony Baxter <anthonybaxter at gmail.com> wrote in message news:<mailman.2329.1093405781.5135.python-list at python.org>...
> I forgot one other point I meant to add - think about when the body of
> a class gets executed, vs when the body of a function gets executed.
> The former is at compile time, the latter is when the function is
> used.

This is a difference between classes and functions.  But maybe it
could be "swept under the rug" in the following way.  Code like this:

using:
    metaclass_decorator(baz)
class foo(bar):
    a = 1
    def moo(self):
        pass

could cause something similar to the following:

foo = metaclass_decorator(baz)('foo', (<class '__main__.bar'>,), {'a':
1, 'moo': <function moo at 0x00879E70>, '__module__': '__main__'})

Granted, this is slightly different from what a function decorator
does.  But the difference probably won't be felt by those who use
class decorators.  Besides the mischief inherent in the introduction
of another namespace floating around behind the __metaclass__ variable
of normal objects, I don't see anything metaclasses can do that class
decorators couldn't.  Class decorators can be passed arguments to
control what function they return (see "baz" above), but this doesn't
seem like a major difference.  So, no, I don't think that class
decorators would be _that_ different from metaclasses.

later,
Jess



More information about the Python-list mailing list