[Python-Dev] PEP 318: Let's propose some useful built-in decorators (original) (raw)

Guido van Rossum guido at python.org
Fri Apr 2 14:50:35 EST 2004


While I ponder the decorator syntax, let's propose some built-in decorators.

We've already got classmethod and staticmethod.

I propose this one to set function attributes:

class func_attrs(objects):

  def __init__(self, **kwds):
      self.attrs = kwds

  def __call__(self, funcobj):
      funcobj.__dict__.update(self.attrs)

Why a class? So you can subclass it like this:

class rst_attrs(func_attrs):

  def __init__(self, arguments, options, content):
      func_attrs.__init__(self, arguments=arguments, options=options,
                                content=content)

Why would you want to do that? So that mistakes in the attribute names would be caught early, and perhaps default values could be provided.

We could also add a standard implementation of synchronized. Or perhaps that should be imported from threading. (But is that really a good thing to copy from Java?)

Other possibilities (all these are pretty much thinking aloud and very much up for votes; and not original, I've seen these proposed before!):

deprecated(comment_string) -- mostly for documentation, but would set the deprecated attribute. The comment_string argument is a string explaining why it is deprecated. Maybe this should also have arguments specifying the first Python release in which it was considered deprecated and the last Python release (if known) where it will be available.

overrides -- indicates that this overrides a base class method. Maybe the default metaclass could check that if this is used there actually is a corresponding base class method, and we might have a "strict" metaclass that checks this is set for all overriding methods.

doctest_script(multi_line_string) -- specifies a doctest script, for use by the doctest module (if this is absent, it will continue to look in the doc string). I like to separate the doctest script from the actual documentation string because, when used for rigorous unit testing (as in Jim&Tim's talk at PyCON), the doctest script is too long to double as reasonable documentation. Maybe this should be imported from the doctest module.

decorator_chain(*args) -- takes any number of decorator arguments and applies them sequentially. Implementation could be:

def decorator_chain(*args): def decorate(func): for arg in args: func = arg(func) return func return decorate

(I don't see a reason to do this with a class.)

I'm not a fan of using function attributes for specifying author, version, copyright etc.; those things usually work on a larger granularity than methods anyway, and belong in the module doc string.

I'm still torn whether to promote defining properties this way:

[propget] def x(self): "Doc string for x" return self.__x

[propset] def x(self, newx): self.__x = newx

[propdel] def x(self): del self.__x

but if people like this (whatever the decorator syntax :) we might as well make this the recommended way to define properties.

Should there be a a separate module from which all those decorators are imported, or should we make them built-ins, following the trend set by classmethod etc.? Not counting the ones that I already mark as to be imported from a special place, like synchronized (from threading.py) and doctest_script (from doctest.py).

Proposals for other standard decorators are welcome!

--Guido van Rossum (home page: http://www.python.org/~guido/)



More information about the Python-Dev mailing list