Thoughts on PEP 318 and Class Decorators

9 AM March 2, 2004

There’s been quite some discussion on python-dev about PEP 318, “Function/Method Decorator Syntax”. PEP 318 proposes an extension that would allow function and class definitions to be modified—“decorated”—immediately after definition.

The PEP also proposes a similar extension for class syntax. Bob Ippolito commented, ”.. but who knows what else it might be useful for… I imagine it would be the end to some metaclass abuses…”.

Here are two uses of class decorators. Both could be done with metaclasses, but are clearer with PEP 318 syntax:

Singleton Classes

Defines a class with a single instance. The instance is assigned the name of the class. Pro: Design intent explicit. Con: The class object no longer has a module level name.

class Foo(object) [singleton]:
    def bar(self):
        print 'hi'

Foo.bar()

Register All Instances

Sometimes you need to register all instances of a class by some attribute. This is a classic use of metaclasses, but the PEP318 syntax is simpler to read and simpler to explain:

class Foo(object) [registerByName]:
    def __init__(self, name):
        self.name = name

Foo(‘fred)

print Foo.Get(‘fred’)

My $0.02

There hasn’t been a lot of discussion (this time around) about whether the list of decorators should go before or after the name being defined. I think it works better before the name, nearer the class keyword:

class [singleton] Foo(object):
    # ... 

I read this as, “A singleton class named Foo which inherits from object”. I prefer this to:

class Foo(object) [singleton] :
    # ... 

which I read as, “A class named Foo which inherits from object and is a singleton”.

I prefer the first form because the [singleton] decorator radically modifies the meaning of the class keyword. This argument carries less weight for a decorator such as [registerByName].

This same argument applies to function decorators: having the decorator list near the def reads more clearly where the decorator changes the meaning of the def keyword, such as with a [classmethod] decorator. There is less of a case for putting the decorator list first when using decorators with less semantic effect, such as [synchronized].

By alang | # | Comments (8)
(Posted to Rants, Software Development and Python)
© 2003-2006 Alan Green