[Baypiggies] JJ: Easy Decorator Example: TimeIt

Shannon -jj Behrens jjinux at gmail.com
Tue Mar 3 10:52:48 CET 2009


On Fri, Feb 27, 2009 at 5:57 PM, Glen Jarvis <glen at glenjarvis.com> wrote:
> JJ,
>     Last night you mentioned you had a real easy code snippet (TimeIt) that
> clearly explains decorators (or what we sometimes refer to as functional
> decorators). Do you mind sending a copy of that code snippet to supplement
> the Newbie Nugget last night? I'm learning about decorators and am starting
> to get my head around them, so any extra code would be helpful.
> Warmest Regards,

No problem.  Tell me if it makes sense :)

-jj

#!/usr/bin/env python

"""Demonstrate function decorators.

BASIC IDEA: Use a function decorator to tell when and how a function should be
logged.  All kinds of things can be logged automatically, including the
function arguments, how long it took to run, and (theoretically) even the
stack.  The syntax looks like:

    @logged("post")
    def hello(name):
        print "Hello,", name

"""

import sys
import time


def logged(when):

    """Log every invocation of the function.

    when -- This should be "pre" or "post".  If "post", then I'll also time
        the function, which may be useful for profiling.

    """

    def log(f, *args, **kargs):
        print >> sys.stderr, """\
Called:
  function: %s
  args: %s
  kargs: %s""" % (`f`, `args`, `kargs`)

    def pre_logged(f):
        def wrapper(*args, **kargs):
            log(f, *args, **kargs)
            return f(*args, **kargs)
        return wrapper

    def post_logged(f):
        def wrapper(*args, **kargs):
            start = time.time()
            try:
                return f(*args, **kargs)
            finally:
                log(f, *args, **kargs)
                print >> sys.stderr, """\
  time delta: %s""" % (time.time() - start)
        return wrapper

    try:
        return {"pre": pre_logged, "post": post_logged}[when]
    except KeyError, e:
        raise ValueError(e)


@logged("post")
def hello(name):
    print "Hello,", name


hello("World!")


More information about the Baypiggies mailing list