[Python-Dev] Class decorators vs metaclasses
Alex Martelli
aleaxit at gmail.com
Sat Nov 5 00:02:42 CET 2005
On 11/4/05, Eyal Lotem <eyal.lotem at gmail.com> wrote:
> I have a few claims, some unrelated, and some built on top of each
> other. I would like to hear your responses as to which are
> convincing, which arne't, and why. I think that if these claims are
> true, Python 3000 should change quite a bit.
>
> A. Metaclass code is black magic and few understand how it works,
> while decorator code is mostly understandable, even by non-gurus.
I disagree. I've held many presentations and classes on both
subjects, and while people may INITIALLY feel like metaclasses are
black magic, as soon as I've explained it the fear dissipates. It all
boils down do understanding that:
class Name(Ba,Ses): <<body>>
means
Name = suitable_metaclass('Name', (Ba,Ses), <<dict-built-by-body>>)
which isn't any harder than understanding that
@foo(bar)
def baz(args): ...
means
def baz(args): ...
baz = foo(bar)(baz)
> B. One of Decorators' most powerful features is that they can
> mixed-and-matched, which makes them very powerful for many purposes,
> while metaclasses are exclusive, and only one can be used. This is
Wrong. You can mix as many metaclasses as you wish, as long as
they're properly coded for multiple inheritance (using super, etc) --
just inherit from them all. This is reasonably easy to automate (see
the last recipe in the 2nd ed of the Python Cookbook), too.
> especially problematic as some classes may assume their subclasses
> must use their respective metaclasses. This means classdecorators are
> strictly more powerful than metaclasses, without cumbersome
> convertions between metaclass mechanisms and decorator mechanisms.
The assertion that classdecorators are strictly more powerful than
custom metaclasses is simply false. How would you design
classdecorator XXX so that
@XXX
class Foo: ...
allows 'print Foo' to emit 'this is beautiful class Foo', for example?
the str(Foo) implicit in print calls type(Foo).__str__(Foo), so you
do need a custom type(Foo) -- which is all that is meant by "a custom
metaclass"... a custom type whose instances are classes, that's all.
> C. Interesting uses of classdecorators are allowing super-calling
> without redundantly specifying the name of your class, or your
> superclass.
Can you give an example?
>
> D. Python seems to be incrementally adding power to the core language
> with these features, which is great, but it also causes significant
> overlapping of language features, which I believe is something to
> avoid when possible. If metaclasses are replaced with class
> decorators, then suddenly inheritence becomes a redundant feature.
And how do you customize what "print Foo" emits, as above?
> E. If inheritence is a redundant feature, it can be removed and an
> "inherit" class decorator can be used. This could also reduce all the
> __mro__ clutter from the language along with other complexities, into
> alternate implementations of the inherit classdecorator.
How do you propose to get exactly the same effects as inheritance
(affect every attribute lookup on a class and its instances) without
inheritance? Essentially, inheritance is automated delegation
obtained by having getattr(foo, 'bar') look through a chain of objects
(essentially the __mro__) until an attribute named 'bar' is found in
one of those objects, plus a few minor but useful side effects, e.g.
on isinstance and issubclass, and the catching of exceptions in
try/except statements. How would any mechanism allowing all of these
uses NOT be inheritance?
Alex
More information about the Python-Dev
mailing list