Skip to content

Instantly share code, notes, and snippets.

@mkowoods
Last active August 29, 2015 14:22
Show Gist options
  • Save mkowoods/a6e258f1286f4d235203 to your computer and use it in GitHub Desktop.
Save mkowoods/a6e258f1286f4d235203 to your computer and use it in GitHub Desktop.
from functools import update_wrapper
def decorator(d):
def _d(fn):
return update_wrapper(d(fn), fn)
update_wrapper(_d, d)
return _d
def decorator(d):
return lambda fn: update_wrapper(d(fn), fn)
decorator = decorator(decorator)
@decorator
def n_ary(f):
"""Given binary function f(x, y), return an n_ary function such
that f(x, y, z) = f(x, f(y,z)), etc. Also allow f(x) = x."""
def n_ary_f(x, *args):
if len(args) == 0:
return x
elif len(args) == 1:
return f(x, args[0])
else:
return f(x, n_ary_f(args[0], *args[1:]))
return n_ary_f
@n_ary
def sum_like(x, y = None):
return x + y if y else x
@decorator
def countcalls(f):
"Decorator that makes the function count calls to it in the dict callcounts[f]"
def _f(*args):
callcounts[_f] += 1
return f(*args)
callcounts[_f] = 0
return _f
callcounts = {}
@decorator
def memo(f):
"""Decorator that caches the return value for each call to f(args). Then when called again with same args, we can
just look it up."""
cache = {}
def _f(*args):
try:
return cache[args]
except KeyError:
cache[args] = results = f(*args)
return result
except TypeError:
return f(args)
return _f
print sum_like(1,2,3,4,5,6)
@countcalls
def main(x, y , z):
return sum([x, y, z])
@countcalls
def test():
return 1
@decorator
def trace(f):
"""produces a human readable version of a recursive funciton"""
indent = ' '
def _f(*args):
signature = '%s(%s)' % (f.__name__, ', '.join(map(repr, args)))
print '%s--> %s' % (trace.level*indent, signature)
trace.level += 1
try:
result = f(*args)
print '%s<-- %s == %s' % ((trace.level-1)*indent,
signature, result)
finally:
trace.level -= 1
return result
trace.level = 0
return _f
def disabled(f):
"""can disable existing decorators through assignment e.g. trace = disabled"""
return f
for n in range(50):
main(1, 2, 3)
for n in range(460):
test()
print callcounts
@trace
def fib(n):
if n == 0 or n == 1:
return 1
else:
return fib(n-1) + fib(n-2)
print fib(6) #running this in the browser's IDE will not display the indentations!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment