Docorator Disected

Ron_Adam radam2 at tampabay.rr.com
Tue Apr 5 21:07:51 EDT 2005


On Wed, 06 Apr 2005 00:23:01 GMT, bokr at oz.net (Bengt Richter) wrote:

>I don't know of anything other than the compiler and cpython sources.
>The byte codes are not all the same from version to version, since
>added language features may require new byte code operations, at least
>for efficiency, and (as our postings here show ;-) explaining code
>clearly is as much of a job as writing it. Fortunately, python code
>is pretty readable, and there is a lot of interesting reading in
>
> Python-2.4xxx\Lib\compiler\ and Python-2.4xxx\Lib\compiler\
>
>on your disk if you download the source installation. Lots of
>other goodies as well like demo code etc.

Thanks, I've already downloaded the source as well as CVS, although I
don't have a resent version of VisualC++.  I Tried the Express version
8.0 since it's free, but it fails on the library with link errors.
:-/,  Not that I expected it to work since nothing I could find said
it would.  Probably easier to load up linux. But I don't need a
compiler to read the source.


>
>One of the original examples of decorating was to replace the
>staticmethod and classmethod function calls that had to be done
>after the method defs. So the simplest view goes back to
>
>    @deco
>    def foo(): pass
>
>being the equivalent (except if deco raises and exception) of
>
>    def foo(): pass
>    foo = deco(foo)
>
>The plain name @deco was then allowed to become a simple   xxx.yyy(zzz,...) expression
>returning a callable that would serve like the decorator function a bare name normally
>referred to. And then the mechanism could be cascaded. I suggest looking at the
>code for the simplest cascade of normal decorators. E.g., (putting the example in
>the body of a function makes dis.dis easy ;-)

So the @decorator functionality was a very small incremental change to
the pre compiler. That also explains the nesting behavior of stacked
decorators. A small change with a worth while functionality. :-)

Looks like the @decorator is pseudo function limited to a single
callable as it's body.

(experimenting with a different syntax)

@deco(a):
	def function(x): pass
	function = deco(a)(function)(x)


Stacked, it would be:

@deco1(a):
    @deco2(b):
        def function(x): 
            return x+1
        function = deco2(a)(function)(x)
    function = deco1(b)(function)(x)


Each subsequent stacked _ at _ statement redefines "function" when it
exits.

If I have this correct, this would be the equivalent long hand of two
stacked _ at _ expressions.


Cheers,
Ron




More information about the Python-list mailing list