Generators and Decorators doing my head in ..

Discussion in 'Python' started by simonvc@gmail.com, Sep 6, 2005.

  1. Guest

    Hi Can someone please help me understand this (i shouldn't have tried
    to learn decorators and generators at the same time..).

    Im trying to create a decorator that counts the number of times a
    function is run. Somthing like:

    def FunctionCounter():
    n=0
    while 1:
    yield n
    n=n+1

    def logFunctionCalls(function):
    print "Entering function:", function.__name__, ec.next()
    return function

    @logFunctionCalls
    def doWork():
    print "Doing Work"


    doWork()

    Where "ec" is a generator that is created inside logFunctionCalls if it
    doesnt already exist.
    Im thinking this has somthing to do with anonymous generators, but im
    not sure how you create or access these..

    Apologies in advance if this is moronic.
    , Sep 6, 2005
    #1
    1. Advertising

  2. Paul McGuire Guest

    Compare this to your original:

    def logFunctionCalls(function):
    ec = FunctionCounter()
    def decoratedFunction(*args,**kwargs):
    print "Entering function:", function.__name__, ec.next()
    function(*args,**kwargs)
    return decoratedFunction

    @logFunctionCalls
    def doWork():
    print "Doing Work"

    doWork()
    doWork()

    (This is a quick-and-dirty example, but it works. A proper iterator
    would do more to preserve the identity, docstring, etc. of the
    underlying doWork() function. See the decorator library page on the
    Python Wiki, at http://wiki.python.org/moin/PythonDecoratorLibrary.)

    Also, look into the treasure trove that is itertools, especially
    itertools.count.

    -- Paul
    Paul McGuire, Sep 6, 2005
    #2
    1. Advertising

  3. wrote:
    > Im trying to create a decorator that counts the number of times a
    > function is run.


    Your code doesn't work because decorators are run at function creation
    time, not at function run time. Try this instead:


    from itertools import count

    def logFunctionCalls(function):
    times = count()
    def newfunction(*args, **kwargs):
    print "Entering function:", function.__name__, times.next()
    return function(*args, **kwargs)
    newfunction.__doc__ = function.__doc__
    newfunction.__name__ = function.__name__
    return newfunction

    @logFunctionCalls
    def doWork():
    print "Doing work..."
    Leif K-Brooks, Sep 6, 2005
    #3
  4. Paul McGuire wrote:
    (snip)

    > (This is a quick-and-dirty example, but it works. A proper iterator


    s/iterator/decorator/

    (snip)
    --
    bruno desthuilliers
    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
    p in ''.split('@')])"
    bruno modulix, Sep 6, 2005
    #4
  5. Guest

    Fantastic, thanks Leif and Paul, My problem is that i thought the
    decorator worked at the function runtime, not when the function gets
    created.
    , Sep 6, 2005
    #5
  6. I usually point out my decorator module
    (http://www.phyast.pitt.edu/~micheles/python/decorator.zip) to simplify
    decorator usage. In this case you would use it as follows:

    from decorator import decorator

    @decorator # convert logFunctionCalls into a decorator
    def logFunctionCalls(function, *args, **kwargs):
    try: # increment the counter
    function.counter += 1
    except AttributeError: # first call, there is no counter attribute
    function.counter = 1
    print "Entering function:", function.__name__, function.counter
    return function(*args, **kwargs)

    @logFunctionCalls
    def f():
    pass

    f()
    f()
    f()

    help(f)

    The whole point of the decorator module is that the signature of
    the original function is left unchanged (i.e. in this case the
    decorated f is still a thunk, not a generic function f(*args, **kw)).
    HTH,

    Michele Simionato
    Michele Simionato, Sep 7, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Brian W
    Replies:
    10
    Views:
    773
    Brian W
    Jul 2, 2003
  2. showme

    PHP and ASP.NET go HEAD to HEAD

    showme, Jul 8, 2004, in forum: ASP .Net
    Replies:
    13
    Views:
    725
    Sherif ElMetainy
    Jul 10, 2004
  3. Karl
    Replies:
    0
    Views:
    395
  4. Arien Malec

    PEP 318 decorators are not Decorators

    Arien Malec, Aug 13, 2004, in forum: Python
    Replies:
    11
    Views:
    570
    Arien Malec
    Aug 16, 2004
  5. Replies:
    7
    Views:
    194
    Ian Kelly
    Sep 12, 2012
Loading...

Share This Page