Source code for decorators

#!/usr/bin/python
# https://github.com/tokland/pyeuler/blob/master/pyeuler/toolset.py

import functools
# Decorators

"""
#doen't work as expected...
#http://wiki.python.org/moin/PythonDecoratorLibrary
def memoize(obj):
    def reset():
        obj.cache = {}
    obj._reset=reset
    obj._reset()
    cache=obj.cache
    @functools.wraps(obj)
    def memoizer(*args, **kwargs):
        if args not in cache:
            cache[args] = obj(*args, **kwargs)
        return cache[args]
    return memoizer
"""

[docs]def memoize(f, maxcache=None, cache={}): '''Decorator to keep a cache of input/output for a given function''' cachelen = [0] def g(*args, **kwargs): key = (f, tuple(args), frozenset(kwargs.items())) if maxcache is not None and cachelen[0] >= maxcache: return f(*args, **kwargs) if key not in cache: cache[key] = f(*args, **kwargs) cachelen[0] += 1 return cache[key] return g
[docs]class tail_recursive(object): """Tail recursive decorator.""" # Michele Simionato's version CONTINUE = object() # sentinel
[docs] def __init__(self, func): self.func = func self.firstcall = True
[docs] def __call__(self, *args, **kwd): try: if self.firstcall: # start looping self.firstcall = False while True: result = self.func(*args, **kwd) if result is self.CONTINUE: # update arguments args, kwd = self.argskwd else: # last call break else: # return the arguments of the tail call self.argskwd = args, kwd return self.CONTINUE except: # reset and re-raise self.firstcall = True raise else: # reset and exit self.firstcall = True return result
[docs]class persistent(object):
[docs] def __init__(self, it): self.it = it
[docs] def __getitem__(self, x): self.it, temp = tee(self.it) if type(x) is slice: return list(islice(temp, x.start, x.stop, x.step)) else: return islice(temp, x, x + 1).next()
[docs] def __iter__(self): self.it, temp = tee(self.it) return temp