Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #63545

Re: Understanding decorator and class methods

Path csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!news.mixmin.net!feeds.phibee-telecom.net!newsfeed.xs4all.nl!newsfeed3.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail
Return-Path <python-python-list@m.gmane.org>
X-Original-To python-list@python.org
Delivered-To python-list@mail.python.org
X-Spam-Status OK 0.000
X-Spam-Evidence '*H*': 1.00; '*S*': 0.00; 'essentially': 0.04; '*not*': 0.07; 'args': 0.07; 'attribute': 0.07; 'method.': 0.07; 'attributes': 0.09; 'decorator': 0.09; 'method,': 0.09; 'methods,': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'wrapped': 0.09; 'def': 0.12; 'jan': 0.12; 'translation': 0.12; '*args):': 0.16; 'args.': 0.16; 'argument:': 0.16; 'behavior,': 0.16; 'callable': 0.16; 'example)': 0.16; 'example?': 0.16; 'itself,': 0.16; 'magic': 0.16; 'merely': 0.16; 'param': 0.16; 'positional': 0.16; 'received:80.91.229.3': 0.16; 'received:plane.gmane.org': 0.16; 'reedy': 0.16; 'subject:class': 0.16; 'typeerror:': 0.16; 'wrote:': 0.18; 'work,': 0.20; 'print': 0.22; 'header:User-Agent:1': 0.23; 'class.': 0.26; 'equivalent': 0.26; 'second': 0.26; 'pass': 0.26; 'asking': 0.27; 'gets': 0.27; 'header:X-Complaints-To:1': 0.27; 'header:In-Reply-To:1': 0.27; 'function': 0.29; 'getting': 0.31; 'explained': 0.31; 'invoke': 0.31; 'prints': 0.31; 'class': 0.32; 'another': 0.32; 'skip:_ 10': 0.34; 'classes': 0.35; 'but': 0.35; 'method': 0.36; 'to:addr :python-list': 0.38; 'pm,': 0.38; 'explain': 0.39; 'does': 0.39; 'to:addr:python.org': 0.39; 'received:org': 0.40; 'received:173': 0.61; 'email addr:gmail.com': 0.63; 'become': 0.64; 'therefore': 0.72; 'special': 0.74; 'decorate': 0.84; 're-type': 0.84; 'received:fios.verizon.net': 0.84; 'trouble.': 0.91
X-Injected-Via-Gmane http://gmane.org/
To python-list@python.org
From Terry Reedy <tjreedy@udel.edu>
Subject Re: Understanding decorator and class methods
Date Wed, 08 Jan 2014 19:20:14 -0500
References <d4d38119-b5b8-415a-bb7b-5d544907df3e@googlegroups.com>
Mime-Version 1.0
Content-Type text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding 7bit
X-Gmane-NNTP-Posting-Host pool-173-75-254-207.phlapa.fios.verizon.net
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0
In-Reply-To <d4d38119-b5b8-415a-bb7b-5d544907df3e@googlegroups.com>
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.15
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <https://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list/>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <https://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
Newsgroups comp.lang.python
Message-ID <mailman.5216.1389226841.18130.python-list@python.org> (permalink)
Lines 67
NNTP-Posting-Host 2001:888:2000:d::a6
X-Trace 1389226841 news.xs4all.nl 2975 [2001:888:2000:d::a6]:44485
X-Complaints-To abuse@xs4all.nl
Xref csiph.com comp.lang.python:63545

Show key headers only | View raw


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 | NextPrevious in thread | Find similar | Unroll thread


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