[Tutor] decorators (the "at" sign)?

Siren Saren siren99 at yahoo.com
Sun Oct 31 15:49:10 CET 2010


Thanks for this very helpful post, Lie.  I find decorators quite interesting and am always looking for new ways to understand and use them.  Your trace function is fun, and I added it to my decorator library.  In response to your point about event-handling in GUIs:

I haven't used pyqt that extensively yet, but it does have a decorator-based syntax for event-handling, which is more or less what you described.  Its concept of events may be slightly different -- signals and slots -- but it's just a layer of abstraction on 'mouse-right-button-click-event,' so hopefully not unwelcome.  I've been impressed with them so far.  I hate GUI programming, and even got into programming in part to avoid GUIs, but I find it easy enough to make something with pyqt (using decorators) that a customized GUI is a decent alternative to just making command line scripts, especially if your working with anything visual that you'd like to display.

Cheers,
Soren

--- On Tue, 10/26/10, Lie Ryan <lie.1296 at gmail.com> wrote:

From: Lie Ryan <lie.1296 at gmail.com>
Subject: Re: [Tutor] decorators (the "at" sign)?
To: tutor at python.org
Date: Tuesday, October 26, 2010, 12:30 PM

On 10/26/10 13:46, Alex Hall wrote:
> Hi all,
> Now that I am able to run the source code of an open source
> application I hope to one day help develop, I am trying to understand
> how it works. One thing I keep seeing is an at sign followed by a
> word, usually (maybe always) immediately preceeding a function
> definition. For example, and I know this exact code will not make much
> sense, but it gives the idea:
> class Bing(Messages, Updating, Dismissable):
> 
>  @set_index
>  def get_url(self, index=None):
>   return self.storage[index]['Url']
> 
> What is the "@set_index" for? Specifically, what is the at sign doing?
> Google was only able to provide me with a very vague idea of what is
> going on, though it seems to crop up a lot in classmethod and
> staticmethod calls (not sure about those either). I read PEP 318, but
> it was not much help since I am coming at this having no idea what I
> am looking at. The PEP did explain why I have never run into this
> before, though - it is apparently specific to Python. I see this sort
> of thing all over this source code so it seems like a good idea to get
> exactly what it is for. TIA!


The decorator syntax is really just a shorthand, from this:

@decorator
def func(arg):
    pass

is equivalent to:

def func(arg):
    pass
func = decorator(func)


basically, a decorator is a function that takes an function as a
parameter/callable and (usually) returns another function/callable as
return value.


A slightly advanced usage of decorator:

def trace(func):
    """ trace will print the func's name, the number of times
        func have been called, the arguments it's called with,
        and the return value of func whenever func is called.
    """

    # define an inner function
    def _decorator(arg):
        print ("The %sth call of %s with arg: %s" %
            (_decorator._numcall, func.__name__, arg))

        _decorator._numcall += 1
        ret = func(arg)

        print "finished", func.__name__, "returns:", ret

        return ret

    # this is used to store the number of times
    # the decorated function is called
    _decorator._numcall = 0

    # disable the decorator when debugging is enabled
    if __debug__: # or: return _decorator if __debug__ else func
        return _decorator
    else:
        return func

@trace
def twice(arg):
    return 2 * arg
# the @trace makes it as if you do this:
# twice = trace(twice)



$ # let's start the program
$ python decor.py
The 0th call of twice() with arg: 30
finished twice() returns: 60
The 1th call of twice() with arg: 3
finished twice() returns: 6
The 2th call of twice() with arg: 4
finished twice() returns: 8
74
$
$ # now call it with debugging disabled:
$ python -O decor.py
74


another nifty use of decorator is for event handling for a hypothetical
GUI toolkit (I've yet to actually see a toolkit that uses this syntax yet):

@button.on_click
def shoot(button):
    ...
@window.on_keypress('p')
def pause(key):
    ...


other built-in functions designed for decorator syntax is @property,
@classmethod, and @instancemethod. Decorator can become extremely
powerful when combined with the descriptor protocol (.__get__, .__set__).

_______________________________________________
Tutor maillist  -  Tutor at python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor



      
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20101031/ebf50ec7/attachment-0001.html>


More information about the Tutor mailing list