Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #63545
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Subject | Re: Understanding decorator and class methods |
| Date | 2014-01-08 19:20 -0500 |
| References | <d4d38119-b5b8-415a-bb7b-5d544907df3e@googlegroups.com> |
| Newsgroups | comp.lang.python |
| Message-ID | <mailman.5216.1389226841.18130.python-list@python.org> (permalink) |
On 1/8/2014 2:56 PM, axis.of.weasel@gmail.com wrote: > can someone please explain why the following works, in contrast to the second example? Because function attributes of classes become instance methods, with special behavior, when accessed via an instance of the class. > def decorator(func): > def on_call(*args): > print args > return func(args) This has to be func(*args) (as in second example) or one gets TypeError: bar() missing 1 required positional argument: 'param1' Did you re-type instead of pasting? > return on_call > > class Foo: > @decorator > def bar(self, param1): > print 'inside bar' > > f=Foo() > f.bar(4) # from where is the decorator getting the Foo instance? from args. f.bar(4) == Foo.bar(f, 4) == on_call(*args), which prints args (tuple f,4) and calls func(*args) == Foo.<real bar>(f, 4) which prints 'inside bar' > I understand why the following works/does not work > > class decorator2: > def __init__(self, func): > self.func=func > def __call__(self, *args): > self.func(*args) > > class Foo2: > @decorator2 > def bar2(self, param): pass Using a class decorator to decorate an instance method of another class is asking for trouble. As explained below, the result is no longer an instance method. > f2 = Foo2() > Foo2.bar2(f2, 4) # works, Foo2 instance and param are passed to decorator2 call > f2.bar2(4) # does not work, Foo2 instance is missing, decorator2 cannot invoke method bar Remember that @deco def f(): pass is essentially equivalent to def f(): pass f = deco(f) Decorator decorator replaces a function with a function. So the wrapped bar is still seen as an instance method, so f.bar(x) gets the magic instance method translation to Foo.bar(f, x). Decorator2 replaces function bar with a callable instance of itself, which is *not* a 'function' and which therefore is not seen as an instance method, but merely a callable attribute of Foo2. So f.bar == Foo.bar, and you would need f2.bar(f2, 4). -- Terry Jan Reedy
Back to comp.lang.python | Previous | Next — Previous in thread | Find similar | Unroll thread
Understanding decorator and class methods axis.of.weasel@gmail.com - 2014-01-08 11:56 -0800 Re: Understanding decorator and class methods Rotwang <sg552@hotmail.co.uk> - 2014-01-08 23:17 +0000 Re: Understanding decorator and class methods Terry Reedy <tjreedy@udel.edu> - 2014-01-08 19:20 -0500
csiph-web