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" <[EMAIL PROTECTED]> escribió en el mensaje > news:[EMAIL PROTECTED] > > > 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 -- http://mail.python.org/mailman/listinfo/python-list