134 lines
3.3 KiB
Plaintext
134 lines
3.3 KiB
Plaintext
PEP: 3129
|
||
Title: Class Decorators
|
||
Version: $Revision$
|
||
Last-Modified: $Date$
|
||
Author: Collin Winter <collinwinter@google.com>
|
||
Status: Final
|
||
Type: Standards Track
|
||
Content-Type: text/x-rst
|
||
Created: 01-May-2007
|
||
Python-Version: 3.0
|
||
Post-History: 07-May-2007
|
||
|
||
|
||
Abstract
|
||
========
|
||
|
||
This PEP proposes class decorators, an extension to the function
|
||
and method decorators introduced in :pep:`318`.
|
||
|
||
|
||
Rationale
|
||
=========
|
||
|
||
When function decorators were originally debated for inclusion in
|
||
Python 2.4, class decorators were seen as
|
||
:pep:`obscure and unnecessary <318#motivation>`
|
||
thanks to metaclasses. After several years' experience
|
||
with the Python 2.4.x series of releases and an increasing
|
||
familiarity with function decorators and their uses, the BDFL and
|
||
the community re-evaluated class decorators and recommended their
|
||
inclusion in Python 3.0 [#approval]_.
|
||
|
||
The motivating use-case was to make certain constructs more easily
|
||
expressed and less reliant on implementation details of the CPython
|
||
interpreter. While it is possible to express class decorator-like
|
||
functionality using metaclasses, the results are generally
|
||
unpleasant and the implementation highly fragile [#motivation]_. In
|
||
addition, metaclasses are inherited, whereas class decorators are not,
|
||
making metaclasses unsuitable for some, single class-specific uses of
|
||
class decorators. The fact that large-scale Python projects like Zope
|
||
were going through these wild contortions to achieve something like
|
||
class decorators won over the BDFL.
|
||
|
||
|
||
Semantics
|
||
=========
|
||
|
||
The semantics and design goals of class decorators are the same as
|
||
for function decorators (:pep:`318#current-syntax`, :pep:`318#design-goals`);
|
||
the only
|
||
difference is that you're decorating a class instead of a function.
|
||
The following two snippets are semantically identical::
|
||
|
||
class A:
|
||
pass
|
||
A = foo(bar(A))
|
||
|
||
|
||
@foo
|
||
@bar
|
||
class A:
|
||
pass
|
||
|
||
For a detailed examination of decorators, please refer to :pep:`318`.
|
||
|
||
|
||
Implementation
|
||
==============
|
||
|
||
Adapting Python's grammar to support class decorators requires
|
||
modifying two rules and adding a new rule::
|
||
|
||
funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite
|
||
|
||
compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt |
|
||
with_stmt | funcdef | classdef
|
||
|
||
need to be changed to ::
|
||
|
||
decorated: decorators (classdef | funcdef)
|
||
|
||
funcdef: 'def' NAME parameters ['->' test] ':' suite
|
||
|
||
compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt |
|
||
with_stmt | funcdef | classdef | decorated
|
||
|
||
Adding ``decorated`` is necessary to avoid an ambiguity in the
|
||
grammar.
|
||
|
||
The Python AST and bytecode must be modified accordingly.
|
||
|
||
A reference implementation [#implementation]_ has been provided by
|
||
Jack Diederich.
|
||
|
||
|
||
Acceptance
|
||
==========
|
||
|
||
There was virtually no discussion following the posting of this PEP,
|
||
meaning that everyone agreed it should be accepted.
|
||
|
||
The patch was committed to Subversion as revision 55430.
|
||
|
||
|
||
References
|
||
==========
|
||
|
||
.. [#approval]
|
||
https://mail.python.org/pipermail/python-dev/2006-March/062942.html
|
||
|
||
.. [#motivation]
|
||
https://mail.python.org/pipermail/python-dev/2006-March/062888.html
|
||
|
||
.. [#implementation]
|
||
https://bugs.python.org/issue1671208
|
||
|
||
|
||
|
||
Copyright
|
||
=========
|
||
|
||
This document has been placed in the public domain.
|
||
|
||
|
||
|
||
..
|
||
Local Variables:
|
||
mode: indented-text
|
||
indent-tabs-mode: nil
|
||
sentence-end-double-space: t
|
||
fill-column: 70
|
||
coding: utf-8
|
||
End:
|