> def A(): > print 'warp in A' > def why(self, *arg, **kw): > print 'in A' > print self > print arg > print kw > #self(*arg, **kw) > > return why > > class T(object): > @A() > def test(g, out): > print 'in test', out > > it will out put: > > warp in A > in A > <function test at 0x00BF0C70> > () > {} >
> the function why will be called, why? there is no code to call it. When Python first parses your code, every time it runs into '@A', it calls A() in order to get the required decorator function. A needs to return a function object that accepts a single parameter (the function we're decorating), and returns another function object that does the actual work. So, what you need is an extra level of inline functions: def A(*args, **kwds): # You can access the arguments passed to the decorator # here, e.g. if we were called as @A('foo', timeout=10), # args[0] would be 'foo', and kwds['timeout'] would be # 10. *args and **kwds are also accessible in the actual # decorator 'body' _fn() below. This allows you to alter # the behaviour of the decorator based on the types that # have been passed to it. def _decorator(f): # A decorator must always return a function object that # takes a single parameter, which will be the function # we're wrapping when we're actually invoked. That's # the purpose of _decorator(f). def _fn(*_args, **_kwds): # And here's where we define the actual decorator # functionality, three levels deep. *_args and # **_kwds will represent the parameters passed to # the actual function we're wrapping; i.e. in our # case, _args[0] will always be self if we're # decorating a class's instance method, and _args[1] # will be either 'foo' or 'bar'. self = _args[0] name = self.__class__.__name__ print 'in A (calling class: %s)' % name # The last responsibility of this method is to # call the actual function we're wrapping. f(*_args, **_kwds) return _fn return _decorator class T(object): @A() def test(self, out): print 'in test T', out class S(object): @A() def test(self, out): print 'in test S', out if __name__ == '__main__': t = T() t.test('foo') s = S() s.test('bar') % python t.py in A (calling class: T) in test T foo in A (calling class: S) in test S bar Regards, Trent. -- http://mail.python.org/mailman/listinfo/python-list