[Python-Dev] Re: PEP 318: Let's propose some useful built-in decorators (original) (raw)
Isaac Freeman ishnigarrab at earthlink.net
Sat Apr 3 19:00:38 EST 2004
- Previous message: [Python-Dev] Re: PEP 318 bake-off?
- Next message: [Python-Dev] Help with PEP 318
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Here are a few ideas (including a meta-decoration! :)
Of course, I'm biased to first-before-colon style. ;)
--- decorators.py ---
import inspect class decorator: """ An obscenely gratuitous example of decorator usage. Meta-decoration? "One mans use is another man's abuse" """
class decoration:
""" The object that represents the decoration itself. """
def __init__(decor, func, **state):
self.func = func
self.state = {'func': func.__name__}
def __call__(self, *args, **kwds):
""" Called when the function that is decorated by this
decoration is called. (whew) """ self.state.update(inspect.getargvalues(sys._getframe(1))[3])
better way?
return self.decor(self.func, self.state, *args, **kwds)
def options(self, opts=None, **kwd_opts):
self.state.update(opts or kwd_opts)
return self
def __init__(self, decor):
self.decor = decor
def __call__(self, func):
""" Called when the decorator is called to decorate a desired
function. """ init = self.init init.update(kwds) return self.decoration(decor, func)
def fromstate(cls, state=None, **kwd_state) [classmethod]:
""" Make a decoration with a specified initial state """
return lambda fn: cls(fn, state or kwd_state)
or...
Smaller, but can be confusing. (But I guess the whole
meta-function-generator thing is to begin with!)
def decorator2(decor=None, **state): """ Decoration factory. """
def decoration2(func=None, **opts):
""" Decorating function wrapper. """
state.update(opts)
state['func'] = func.__name__
def callit(*args, **kwds):
""" Function replacement. """
state.update(inspect.getargvalues(sys._getframe(1))[3]) #
better way?
decor(func, state, *args, **kwds)
if func:
return callit
else:
return lambda fn: decoration2(fn, **opts)
if decor:
return decoration
else:
return lambda dec: decorator2(dec, state)
def memoized(func, state, *args, **kwds) [decorator]: """ Function wrapper to cache the results of previously evaluated arguments. """ items = kwds.items items.sort() key = (args, tuple(items)) # hope everything is hashable! return ( state.get(key) or state.setdefault(key, func(*args, **kwds)) )
def memoized2(func, state, *args, **kwds) [decorator2]: key = (args, tuple(kwds.items())) return ( state.get(key) or state.setdefault(key, func(*args, **kwds)) )
import sys, time def logged(func, state, *args, **kwds) [decorator.fromstate( output=sys.stdout.write, prefix='%(func)s: ')]: """ Usage for default formatting and output:
def func(*args) [logged]:
pass
Usage for custom formatting and output:
def func(a, b) [logged.options(output=output_func,
prefix="%(func)s %(a)s %(b)i")]:
pass
String replacements include 'func' which is the function's name,
as well as all arguments to the function such that "%(a)s" would become the value of the argument named 'a'. """ p = '[%s] %s' % (time.time(), state['prefix'] % state) state'output'
def logged2(func, state, *args, **kwds) [decorator2( output=sys.stdout.write, prefix='%(func)s: ')]: """ Usage for default formatting and output:
def func(*args) [logged2]:
pass
Usage for custom formatting and output:
def func(a, b) [logged2(output=output_func,
prefix="%(func)s %(a)s %(b)i")]:
pass
String replacements include 'func' which is the function's name,
as well as all arguments to the function such that "%(a)s" would become the value of the argument named 'a'. """ p = '[%s] %s' % (time.time(), state['prefix'] % state) state'output'
demo function
def factorial(n) [memoized, logged.options(output=sys.stdout.write, prefix='factorial for %(n)s: ')]: """ Computes the factorial of n """ print "fact(%i)" % n if n == 1: return 1 else: return n * fact(n - 1) # make tail_recursive decorator(?)
def factorial2(n) [memoized, logged2(output=sys.stdout.write, prefix='factorial for %(s): ')]: """ Computes the factorial of n """ print "fact(%i)" % n if n == 1: return 1 else: return n * fact(n - 1)
- Previous message: [Python-Dev] Re: PEP 318 bake-off?
- Next message: [Python-Dev] Help with PEP 318
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]