recursive decorator
Ethan Furman
ethan at stoneleaf.us
Fri Sep 4 13:03:17 EDT 2009
Michele Simionato wrote:
> On Sep 3, 6:41 pm, Ethan Furman <et... at stoneleaf.us> wrote:
>
>>The original thread by Bearophile:
>> http://mail.python.org/pipermail/python-list/2009-May/711848.html
>
>
> I have read the thread. What Bearophile wants can be implemented with
> a bytecode hack, no
> need for the decorator module. Let me call 'recur' the self-function,
> like in Clojure.
> You can define a decorator that makes "self-conscious" a recursive
> function as follows:
>
> # requires byteplay by Noam Raphael
> # see http://byteplay.googlecode.com/svn/trunk/byteplay.py
> from byteplay import Code, LOAD_GLOBAL, STORE_FAST, LOAD_FAST
>
> def enable_recur(f):
> print f.func_code.co_names
> if 'recur' not in f.func_code.co_names:
> return f # do nothing on non-recursive functions
> c = Code.from_code(f.func_code)
> c.code[1:1] = [(LOAD_GLOBAL, f.__name__), (STORE_FAST, 'recur')]
> for i, (opcode, value) in enumerate(c.code[2:]):
> if opcode == LOAD_GLOBAL and value == 'recur':
> c.code[i+2] = (LOAD_FAST, 'recur')
> f.func_code = c.to_code()
> return f
>
> ## example of use
>
> @enable_recur
> def f(x):
> if x == 1:
> return 1
> else:
> return x*recur(x-1)
>
> print f(4) # =>24
>
>
> Please accept this without explanation since it would take me a lot of
> time
> to explain how it works. Just accept that bytecode hacks are
> incredible
> (and nonportable too) ;-)
>
> Michele Simionato
No worries -- not sure I would understand the explanation at this point,
anyway!
Just to verify, using the decorator module is portable, yes?
~Ethan~
More information about the Python-list
mailing list