Decorator

bruno at modulix onurb at xiludom.gro
Fri May 12 12:22:33 EDT 2006


Martin Blume wrote:
> "bruno at modulix" schrieb 
> 
(snip)
>>def deco(func):
>>  print "decorating %s" % func.__name__
>>  def _wrapper(*args, **kw):
>>    print "%s called " % func.__name__
>>    res = func(*args, **kw)
>>    print "%s returned %s" % (func.__name__, str(res))
> 
>       return res
>       ^^^^^^^^^^
> Shouldn't here be a return res, so that wrapper
> behaves like the original function?

oops, my bad :(
And yes, of course.

> 
>>  return _wrapper
>>
>># python < 2.4
>>def somefunc():
>>  print "in somefunc"
>>  return 42
>>
>>somefunc = deco(somefunc)
>>
> 
> Thanks for the explanation.
> 
> 
> Another question: Isn't decorating / wrapping usually
> done at runtime,

It is. I mean, using decorator syntax, this is done during import, which
happens at runtime.

> so that the @deco notation is pretty
> useless (because you'd have to change the original 
> code)?

I don't understand your question.

> What do I miss here?

Ok, I get it (well, I think...).

The use case for @decorator is for wrapping functions or method *in the
module/class itself*. It's not for module client code (but this of
course doesn't prevent client code to dynamically add other wrappers...)

One of the primary use case makes this pretty clear IHMO : classmethod
and staticmethod :

# python < 2.4:
class Cleese(object):
  def doSillyWalk(cls):
     pass
  doSillyWalk = classmethod(doSillyWalk)

# python >= 2.4:
class Cleese(object):
  @classmethod
  def doSillyWalk(cls):
     pass

Another example : CherryPy uses decorators to mark methods which are
'published' (ie: are action controllers responding to a given URL)


HTH
-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"



More information about the Python-list mailing list