[Python-Dev] @decoration of classes (original) (raw)

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