On Fri, Sep 4, 2009 at 3:53 PM, Edward K. Ream <span dir="ltr">&lt;<a href="mailto:edreamleo@gmail.com">edreamleo@gmail.com</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="im"><br></div><div><div class="h5">Also, it is in no way an abuse of decorators to use them in
unexpected, unusual, creative ways, provided only that you are not
relying on some undocumented accidental feature.<br></div></div></blockquote><div class="h5"><br>Inspired by this thread, I decided to deepen my understanding of decorators.  To state my conclusion first, to truly understand decorators it is a good idea to completely ignore pep 318 and all related tutorials :-)<br>
<br>Indeed, everything you need to know, (everything there *is* to know) about decorators is in the Reference Guide: <a href="http://docs.python.org/reference/compound_stmts.html#function-definitions">http://docs.python.org/reference/compound_stmts.html#function-definitions</a><br>
<br>Specifically, the reference guide has only this to say about decorators:<br><br>QQQ<br><p id="index-768">A function definition may be wrapped by one or more <a class="reference external" href="http://docs.python.org/glossary.html#term-decorator"><em class="xref">decorator</em></a> expressions.
Decorator expressions are evaluated when the function is defined, in the scope
that contains the function definition.  The result must be a callable, which is
invoked with the function object as the only argument. The returned value is
bound to the function name instead of the function object.  Multiple decorators
are applied in nested fashion. For example, the following code:
</p><div class="highlight-python"><div class="highlight"><pre><span class="nd">@f1</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span><br><span class="nd">@f2</span><br><span class="k">def</span> <span class="nf">func</span><span class="p">():</span> <span class="k">pass</span><br>
</pre></div>
</div>
<p>is equivalent to:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">func</span><span class="p">():</span> <span class="k">pass</span><br><span class="n">func</span> <span class="o">=</span> <span class="n">f1</span><span class="p">(</span><span class="n">arg</span><span class="p">)(</span><span class="n">f2</span><span class="p">(</span><span class="n">func</span><span class="p">))</span></pre>
</div>
</div><p id="index-768">QQQ<br></p>Imo, this is a rare example where the most consise explanation is also the clearest and best.  It is best because it does not deal with the blah blah blah of expectations.  It implicitly says that one is free to use decorators in *any* way, subject only to the constraint that the decorator expression evaluates to a callable.  Failure of the decorator to evaluate to a callable of *some* kind is the only way to &quot;abuse&quot; a decorator, and the compiler will not allow such abuse :)  In particular, there is no requirement that the callable be in *any* way related to func!<br>
<br>The simplicity of decorators renders them neither useless nor uninteresting.  Unlike tutorials, the reference does not tell how to implement, say, @trace.  We are left with a sense of possibility.<br><br>Edward<br></div>
</div>-------------------------------------------------------------------<br>Edward K. Ream email: <a href="mailto:edreamleo@gmail.com">edreamleo@gmail.com</a><br>Leo: <a href="http://webpages.charter.net/edreamleo/front.html">http://webpages.charter.net/edreamleo/front.html</a><br>
--------------------------------------------------------------------<br><br>