Decorators inside of class and decorator parameters
Gabriel Genellina
gagsl-py at yahoo.com.ar
Sat Jan 13 23:07:00 EST 2007
"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