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@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor