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. _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com