Decorators inside of class and decorator parameters
ptwobrussell at gmail.com
Sun Jan 14 18:05:46 CET 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.
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:
> 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,
> 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
> Gabriel Genellina
More information about the Python-list