[Python-Dev] PEP 318 - posting draft

Jack Diederich jack at performancedrivers.com
Wed Mar 24 11:16:51 EST 2004


On Wed, Mar 24, 2004 at 10:00:53AM -0500, Bob Ippolito wrote:
> 
> On Mar 24, 2004, at 9:28 AM, Guido van Rossum wrote:
> 
> >>Actually, it should be deleted and the PEP updated.  Michael's latest 
> >>patch
> >>apparently supports class decorators, so it's no longer an extension.
> >
> >But while you're at it, please add to the PEP that I don't like the
> >idea of class decorators.  I think they don't solve a real problem,
> >unlike function decorators, and I think that making classes and
> >functions more similar just adds confusion.
> 
> I disagree.  There's definitely a use case for something less permanent 
> than a metaclass that gets a reference to a class immediately after 
> creation but before it ends up in the module namespace.

I would use it with factories as (ex 1):

class SubCollect(Collect) [register(db=4, name='newsletter')]: pass

instead of (ex 2):

class SubCollect(Collect): pass
register(SubCollect, db=4, name='newsletter')

or the metaclass [ab]use (ex 3):

class Collect(object):
  __metaclass__ = register_anyone_who_derives_from_us

class SubCollect(Collect):
  db = 4              # metaclass looks for cls.db
  name = 'newsletter' # and cls.name


I actually moved from using #2 to #3 in real life.
#2 is typo prone, and if you omit the register() call you're SOL.
It also has the same distance problem as the 'staticmethod' call,
it is hard to see the call because it is always after the class
definition.

I would prefer doing it the #1 way.  It doesn't modify the class
(it just registers it with a Factory) but it puts the meta information
about the class registration in a place that is easy to see and understand
without littering the __dict__ with meta info like #3.  Decoration
makes it very easy to see which classes register and which don't.
The metaclass way requires an ugly DO_NOT_REGISTER_ME = 1 for intermediate
classes that the factory shouldn't care about.

The decorator is the only one that makes it really obvious what
we're doing.

The end calls look like

guy_cls = find_collect_class(db=4, name='newsletter')

-jackdied




More information about the Python-Dev mailing list