Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / v9 / html / python / whatsnew / node6.html
CommitLineData
920dae64
AT
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<html>
3<head>
4<link rel="STYLESHEET" href="whatsnew24.css" type='text/css' />
5<link rel="SHORTCUT ICON" href="../icons/pyfav.png" type="image/png" />
6<link rel='start' href='../index.html' title='Python Documentation Index' />
7<link rel="first" href="whatsnew24.html" title='What's New in Python 2.4' />
8<link rel='contents' href='contents.html' title="Contents" />
9<link rel='last' href='about.html' title='About this document...' />
10<link rel='help' href='about.html' title='About this document...' />
11<link rel="next" href="node7.html" />
12<link rel="prev" href="node5.html" />
13<link rel="parent" href="whatsnew24.html" />
14<link rel="next" href="node7.html" />
15<meta name='aesop' content='information' />
16<title>5 PEP 318: Decorators for Functions and Methods</title>
17</head>
18<body>
19<DIV CLASS="navigation">
20<div id='top-navigation-panel' xml:id='top-navigation-panel'>
21<table align="center" width="100%" cellpadding="0" cellspacing="2">
22<tr>
23<td class='online-navigation'><a rel="prev" title="4 PEP 292: Simpler"
24 href="node5.html"><img src='../icons/previous.png'
25 border='0' height='32' alt='Previous Page' width='32' /></A></td>
26<td class='online-navigation'><a rel="parent" title="What's New in Python"
27 href="whatsnew24.html"><img src='../icons/up.png'
28 border='0' height='32' alt='Up One Level' width='32' /></A></td>
29<td class='online-navigation'><a rel="next" title="6 PEP 322: Reverse"
30 href="node7.html"><img src='../icons/next.png'
31 border='0' height='32' alt='Next Page' width='32' /></A></td>
32<td align="center" width="100%">What's New in Python 2.4</td>
33<td class='online-navigation'><a rel="contents" title="Table of Contents"
34 href="contents.html"><img src='../icons/contents.png'
35 border='0' height='32' alt='Contents' width='32' /></A></td>
36<td class='online-navigation'><img src='../icons/blank.png'
37 border='0' height='32' alt='' width='32' /></td>
38<td class='online-navigation'><img src='../icons/blank.png'
39 border='0' height='32' alt='' width='32' /></td>
40</tr></table>
41<div class='online-navigation'>
42<b class="navlabel">Previous:</b>
43<a class="sectref" rel="prev" href="node5.html">4 PEP 292: Simpler</A>
44<b class="navlabel">Up:</b>
45<a class="sectref" rel="parent" href="whatsnew24.html">What's New in Python</A>
46<b class="navlabel">Next:</b>
47<a class="sectref" rel="next" href="node7.html">6 PEP 322: Reverse</A>
48</div>
49<hr /></div>
50</DIV>
51<!--End of Navigation Panel-->
52
53<H1><A NAME="SECTION000600000000000000000">
545 PEP 318: Decorators for Functions and Methods</A>
55</H1>
56
57<P>
58Python 2.2 extended Python's object model by adding static methods and
59class methods, but it didn't extend Python's syntax to provide any new
60way of defining static or class methods. Instead, you had to write a
61<tt class="keyword">def</tt> statement in the usual way, and pass the resulting
62method to a <tt class="function">staticmethod()</tt> or <tt class="function">classmethod()</tt>
63function that would wrap up the function as a method of the new type.
64Your code would look like this:
65
66<P>
67<div class="verbatim"><pre>
68class C:
69 def meth (cls):
70 ...
71
72 meth = classmethod(meth) # Rebind name to wrapped-up class method
73</pre></div>
74
75<P>
76If the method was very long, it would be easy to miss or forget the
77<tt class="function">classmethod()</tt> invocation after the function body.
78
79<P>
80The intention was always to add some syntax to make such definitions
81more readable, but at the time of 2.2's release a good syntax was not
82obvious. Today a good syntax <em>still</em> isn't obvious but users are
83asking for easier access to the feature; a new syntactic feature has
84been added to meet this need.
85
86<P>
87The new feature is called ``function decorators''. The name comes
88from the idea that <tt class="function">classmethod</tt>, <tt class="function">staticmethod</tt>,
89and friends are storing additional information on a function object;
90they're <em>decorating</em> functions with more details.
91
92<P>
93The notation borrows from Java and uses the "<tt class="character">@</tt>" character as an
94indicator. Using the new syntax, the example above would be written:
95
96<P>
97<div class="verbatim"><pre>
98class C:
99
100 @classmethod
101 def meth (cls):
102 ...
103</pre></div>
104
105<P>
106The <code>@classmethod</code> is shorthand for the
107<code>meth=classmethod(meth)</code> assignment. More generally, if you have
108the following:
109
110<P>
111<div class="verbatim"><pre>
112@A @B @C
113def f ():
114 ...
115</pre></div>
116
117<P>
118It's equivalent to the following pre-decorator code:
119
120<P>
121<div class="verbatim"><pre>
122def f(): ...
123f = A(B(C(f)))
124</pre></div>
125
126<P>
127Decorators must come on the line before a function definition, and
128can't be on the same line, meaning that <code>@A def f(): ...</code> is
129illegal. You can only decorate function definitions, either at the
130module level or inside a class; you can't decorate class definitions.
131
132<P>
133A decorator is just a function that takes the function to be decorated
134as an argument and returns either the same function or some new
135callable thing. It's easy to write your own decorators. The
136following simple example just sets an attribute on the function
137object:
138
139<P>
140<div class="verbatim"><pre>
141&gt;&gt;&gt; def deco(func):
142... func.attr = 'decorated'
143... return func
144...
145&gt;&gt;&gt; @deco
146... def f(): pass
147...
148&gt;&gt;&gt; f
149&lt;function f at 0x402ef0d4&gt;
150&gt;&gt;&gt; f.attr
151'decorated'
152&gt;&gt;&gt;
153</pre></div>
154
155<P>
156As a slightly more realistic example, the following decorator checks
157that the supplied argument is an integer:
158
159<P>
160<div class="verbatim"><pre>
161def require_int (func):
162 def wrapper (arg):
163 assert isinstance(arg, int)
164 return func(arg)
165
166 return wrapper
167
168@require_int
169def p1 (arg):
170 print arg
171
172@require_int
173def p2(arg):
174 print arg*2
175</pre></div>
176
177<P>
178An example in <a class="rfc" id='rfcref-1445' xml:id='rfcref-1445'
179href="http://www.python.org/peps/pep-0318.html">PEP 318</a> contains a fancier version of this idea that
180lets you both specify the required type and check the returned type.
181
182<P>
183Decorator functions can take arguments. If arguments are supplied,
184your decorator function is called with only those arguments and must
185return a new decorator function; this function must take a single
186function and return a function, as previously described. In other
187words, <code>@A @B @C(args)</code> becomes:
188
189<P>
190<div class="verbatim"><pre>
191def f(): ...
192_deco = C(args)
193f = A(B(_deco(f)))
194</pre></div>
195
196<P>
197Getting this right can be slightly brain-bending, but it's not too
198difficult.
199
200<P>
201A small related change makes the <tt class="member">func_name</tt> attribute of
202functions writable. This attribute is used to display function names
203in tracebacks, so decorators should change the name of any new
204function that's constructed and returned.
205
206<P>
207<div class="seealso">
208 <p class="heading">See Also:</p>
209
210<dl compact="compact" class="seerfc">
211 <dt><a href="http://www.python.org/peps/pep-0318.html"
212 title="Decorators for Functions, Methods and Classes"
213 >PEP 318, <em>Decorators for Functions, Methods and Classes</em></a>
214 <dd>Written
215by Kevin D. Smith, Jim Jewett, and Skip Montanaro. Several people
216wrote patches implementing function decorators, but the one that was
217actually checked in was patch #979728, written by Mark Russell.
218 </dl>
219</div>
220
221<P>
222
223<DIV CLASS="navigation">
224<div class='online-navigation'>
225<p></p><hr />
226<table align="center" width="100%" cellpadding="0" cellspacing="2">
227<tr>
228<td class='online-navigation'><a rel="prev" title="4 PEP 292: Simpler"
229 href="node5.html"><img src='../icons/previous.png'
230 border='0' height='32' alt='Previous Page' width='32' /></A></td>
231<td class='online-navigation'><a rel="parent" title="What's New in Python"
232 href="whatsnew24.html"><img src='../icons/up.png'
233 border='0' height='32' alt='Up One Level' width='32' /></A></td>
234<td class='online-navigation'><a rel="next" title="6 PEP 322: Reverse"
235 href="node7.html"><img src='../icons/next.png'
236 border='0' height='32' alt='Next Page' width='32' /></A></td>
237<td align="center" width="100%">What's New in Python 2.4</td>
238<td class='online-navigation'><a rel="contents" title="Table of Contents"
239 href="contents.html"><img src='../icons/contents.png'
240 border='0' height='32' alt='Contents' width='32' /></A></td>
241<td class='online-navigation'><img src='../icons/blank.png'
242 border='0' height='32' alt='' width='32' /></td>
243<td class='online-navigation'><img src='../icons/blank.png'
244 border='0' height='32' alt='' width='32' /></td>
245</tr></table>
246<div class='online-navigation'>
247<b class="navlabel">Previous:</b>
248<a class="sectref" rel="prev" href="node5.html">4 PEP 292: Simpler</A>
249<b class="navlabel">Up:</b>
250<a class="sectref" rel="parent" href="whatsnew24.html">What's New in Python</A>
251<b class="navlabel">Next:</b>
252<a class="sectref" rel="next" href="node7.html">6 PEP 322: Reverse</A>
253</div>
254</div>
255<hr />
256<span class="release-info">Release 1.01.</span>
257</DIV>
258<!--End of Navigation Panel-->
259<ADDRESS>
260See <i><a href="about.html">About this document...</a></i> for information on suggesting changes.
261</ADDRESS>
262</BODY>
263</HTML>