Understanding decorator and class methods
Rotwang
sg552 at hotmail.co.uk
Wed Jan 8 18:17:22 EST 2014
More information about the Python-list mailing list
Wed Jan 8 18:17:22 EST 2014
- Previous message (by thread): Understanding decorator and class methods
- Next message (by thread): Understanding decorator and class methods
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 08/01/2014 19:56, axis.of.weasel at gmail.com wrote: > can someone please explain why the following works, in contrast to the second example? > > def decorator(func): > def on_call(*args): > print args > return func(args) > 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? > > > > 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 > > > 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 From http://docs.python.org/3/reference/datamodel.html: Instance methods An instance method object combines a class, a class instance and any callable object (normally a user-defined function). [...] User-defined method objects may be created when getting an attribute of a class (perhaps via an instance of that class), if that attribute is a user-defined function object or a class method object. [...] Note that the transformation from function object to instance method object happens each time the attribute is retrieved from the instance. In some cases, a fruitful optimization is to assign the attribute to a local variable and call that local variable. Also notice that this transformation only happens for user-defined functions; other callable objects (and all non-callable objects) are retrieved without transformation. Notice the last sentence in particular. After being decorated by decorator2 Foo2.bar2 is not a user-defined function (i.e. an instance of types.FunctionType), so is not transformed into a method upon being accessed through an instance. I suppose you could create a class that mimics the behaviour of methods, though I don't know why you would want to. The following is tested with 3.3.0; I expect someone who knows more than I will probably be along soon to point out why it's stupid. class decorator3: def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): print('Calling func(self, *%r, **%r)' % (args, kwargs)) return self.func(self.__self__, *args, **kwargs) def __get__(self, instance, owner): self.__self__ = instance return self class Foo3: @decorator3 def bar3(self, param): return self, param >>> f3 = Foo3() >>> f3.bar3('param') Calling func(self, *('param',), **{}) (<__main__.Foo3 object at 0x0000000002BDF198>, 'param')
- Previous message (by thread): Understanding decorator and class methods
- Next message (by thread): Understanding decorator and class methods
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list