Decorators inside of class and decorator parameters

MR ptwobrussell at gmail.com
Sun Jan 14 12:05:46 EST 2007


Thanks so much for your reply.  You've definitely helped me a great
deal on this. Your comment about the difference between define time and
instantiation time cleared things up more than anything, and that also
helped clear up the confusion I was having about "self".

I think the places I've seen decorators called like fooDecorator() must
be using some default arguments in the function signature...so that
part makes a lot more sense now too.

Thanks again!


Gabriel Genellina wrote:
> "MR" <ptwobrussell at gmail.com> escribió en el mensaje
> news:1168728983.541526.202320 at l53g2000cwa.googlegroups.com...
>
> > I have a question about decorators, and I think an illustration would
> > be helpful. Consider the following simple class:
> >
> > #begin code
> > class Foo:
> >    def fooDecorator(f):
> >        print "fooDecorator"
> >
> >        def _f(self, *args, **kw):
> >            return f(self, *args, **kw)
> >
> >        return _f
> >
> >    @fooDecorator
> >    def fooMethod(self):
> >        print "fooMethod"
> >
> > f = Foo()
> > f.fooMethod()
> > #end of code
> >
> > This code runs, and actually serves my purpose. However, I'm a little
> > confused about three things and wanted to try and work through them
> > while I had the time to do so. I believe all of my confusion is related
> > to the parameters related to the fooDecorator:
>
> [I reordered your questions to make the answer a bit more clear]
>
> > -why does this code even work, because the first argument to
> > fooDecorator isn't self
>
> fooDecorator is called when the class is *defined*, not when it's
> instantiated. `self` has no meaning inside it, neither the class to which it
> belongs (Foo does not even exist yet).
> At this time, fooDecorator is just a simple function, being collected inside
> a namespace in order to construct the Foo class at the end. So, you get
> *exactly* the same effect if you move fooDecorator outside the class.
>
> > -how I would pass arguments into the fooDecorator if I wanted to (my
> > various attempts have failed)
>
> Once you move fooDecorator outside the class, and forget about `self` and
> such irrelevant stuff, it's just a decorator with arguments.
> If you want to use something like this:
>    @fooDecorator(3)
>    def fooMethod(self):
> that is translated to:
>    fooMethod = fooDecorator(3)(fooMethod)
> That is, fooDecorator will be called with one argument, and the result must
> be a normal decorator - a function accepting a function an an argument and
> returning another function.
>
> def outerDecorator(param):
>   def fooDecorator(f):
>     print "fooDecorator"
>
>     def _f(self, *args, **kw):
>         print "decorated self=%s args=%s kw=%s param=%s" % (self, args, kw,
> param)
>         kw['newparam']=param
>         return f(self, *args, **kw)
>
>     return _f
>   return fooDecorator
>
> This is the most direct way of doing this without any help from other
> modules - see this article by M. Simoniato
> http://www.phyast.pitt.edu/~micheles/python/documentation.html for a better
> way using its decorator factory.
>
> > -what the difference is between decorating with @fooDecorator versus
> > @fooDecorator()
> Easy: the second way doesn't work :)
> (I hope reading the previous item you can answer this yourself)
>
> > I'm searched the net and read the PEPs that seemed relevant, but I
> > didn't see much about decorators inside of a class like this. Can
> > anyone comment on any of these three things?
> As said in the beginning, there is no use for decorators as methods (perhaps
> someone can find a use case?)
> If you move the example above inside the class, you get exactly the same
> results.
> 
> HTH,
> 
> -- 
> Gabriel Genellina




More information about the Python-list mailing list