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

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