[Python-Dev] @decoration of classes
Jack Diederich
jack at performancedrivers.com
Tue Mar 29 02:22:23 CEST 2005
On Mon, Mar 28, 2005 at 09:25:18AM -0800, Michael Chermside wrote:
> Josiah Carlson writes:
>
> [... stuff about reST and TeX ...]
> > While I have not used it often, I have done the equivalent of decorating
> > classes; it is as natural (though perhaps not quite as useful initially)
> > as decorating functions,
> [... stuff about ice cream and sprinkles ...]
>
> Hmm... the only bit that I found particularly interesting there was the bit
> where you mention that you've used class decorators (without the syntax)
> before.
>
> What did you use them for? After all, the current state of things is "don't
> bother implementing class decorators because there is no compelling use
> case". If you've got some sample use cases, what were they?
>
> For my own part, I observe the following. Because a function decorator
> acts after the function object is created, there are limits to what it
> can do to the function. It can add some markup (eg: set properties or
> doc strings). It can "hook" either before or after the function is
> called. Or it can "veto" the function call and do something else
> instead. In the case of function calls, these are pretty much the
> interesting things you would want to do.
>
> Similarly, because a class decorator acts after the class is created
> there are limits on what it can do. It can modify the class object
> (replacing methods and such). It can add markup. It can replace the
> class with another (perhaps a proxy or some such). But most of these
> are things which are more easily done by a metaclass... and all of
> them *can* be done by metaclasses. The only noticable advantage that
> I see to class decorators over metaclasses is that there's a more
> straightforward way to combine them. And I'm not sure that combining
> metaclasses (or class decorators) is something I want to encourage.
>
> So I'm inclined to use different tools for modifying functions and
> modifying classes because the ways you want to modify them are
> different, and decorators are "tuned" to what people normally want
> to do with functions (like simple wrapping) while metaclasses are
> "tuned" to what people normally want to do with classes (like support
> for inheritance.
>
Metaclasses are a muddle because they can do everything a class can do
and more, since metclasses are to classes as classes are to objects.
>From the bottom up:
objects:
get magic methods from their class
can manipulate non-magic methods and attributes on a per-instance basis
classes:
get magic methods from their metaclass
can create magic methods and attributes used by objects.
Plus anything objects can do
metaclasses:
can create magic methods of a class
can define class methods and attributes
Plus anything a class can do.
Metaclasses are a muddle because we (the royal we) are used to doing most
things at the class level. Defining class methods in a metaclass like this
probably isn't your regular style
>>> class MetaK(type):
... def foo(cls): pass
...
>>> class K:
... __metaclass__ = MetaK
... def bar(cls): pass
... bar = classmethod(bar)
...
>>> K.foo
<bound method MetaK.foo of <class '__main__.K'>>
>>> K.bar
<bound method MetaK.bar of <class '__main__.K'>>
I'm happy using classmethod instead of writing a metaclass everytime I need
a classmethod. I think everyone is class-centric, or we could define static
methods using
class MetaK(type):
def foo(): pass
foo = metaclassmethod(foo) # class method of a type is a static method?
Since I've never wanted to set a type's __repr__ I use metaclasses
as a handy place to do mundane class-level manipulations. I don't actually need
to do type level manipulations.
So that's why I like class decorators, it lets me push type level manipulations
(manipulating a class from its type's __init__ or __new__) down to the class
level where my brain normally hangs out. I just want to change an object's
behavior and I'd welcome a chance to do it by manipulating the class and
not the class's class (which is the object's class's class, yikes!)
-jackdied
ps, I tried to raise a simliar point at PyCon during Alex Martelli's Q&A
but got flustered and screwed it all up.
More information about the Python-Dev
mailing list