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


Groups > comp.lang.python > #17240

Re: AttributeError in "with" statement (3.2.2)

Path csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!ecngs!feeder2.ecngs.de!newsfeed.freenet.ag!news2.euro.net!newsgate.cistron.nl!newsgate.news.xs4all.nl!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; 'python.': 0.04; '"if': 0.04; 'context': 0.04; '*not*': 0.05; 'attributes': 0.05; 'instance,': 0.05; 'interpreter': 0.05; 'parameter': 0.05; 'attribute': 0.07; 'constructor': 0.07; 'method,': 0.07; 'received:verizon.net': 0.07; 'terry': 0.07; 'to)': 0.07; 'python': 0.08; '>>>>': 0.09; 'attributes,': 0.09; 'callable': 0.09; 'callable.': 0.09; 'defined.': 0.09; 'effect.': 0.09; 'instance.': 0.09; 'lambda:': 0.09; 'parameter.': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:80.91.229.12': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'received:lo.gmane.org': 0.09; 'subclass': 0.09; 'used)': 0.09; 'am,': 0.12; 'def': 0.13; 'classes,': 0.13; 'argument': 0.15; 'class,': 0.15; 'method.': 0.15; 'arg': 0.16; 'attribute,': 0.16; 'b()': 0.16; 'callable,': 0.16; 'container.': 0.16; 'definition,': 0.16; 'f()': 0.16; 'fruit': 0.16; 'lambda': 0.16; 'lookup': 0.16; 'manager)': 0.16; 'reedy': 0.16; 'test()': 0.16; 'wed,': 0.17; 'wrote:': 0.18; 'instance': 0.18; 'jan': 0.19; '(which': 0.19; 'dec': 0.22; '(or': 0.22; "doesn't": 0.22; 'header :In-Reply-To:1': 0.22; 'knowing': 0.23; 'statement': 0.23; 'body.': 0.23; 'defined': 0.24; '"this': 0.24; 'says': 0.25; "i'm": 0.26; 'function': 0.27; 'import': 0.27; 'subject:" ': 0.28; 'bit': 0.28; 'pass': 0.29; "skip:' 10": 0.29; 'second': 0.29; 'class': 0.29; 'definition': 0.30; 'operation.': 0.30; 'relation': 0.30; '(the': 0.30; 'usually': 0.31; 'does': 0.32; 'words,': 0.32; 'actual': 0.32; 'idea': 0.32; 'header:User-Agent:1': 0.33; 'actually': 0.33; 'header:X-Complaints-To:1': 0.33; 'there': 0.33; 'object': 0.33; 'rules': 0.34; 'to:addr:python-list': 0.34; 'eric': 0.34; 'too': 0.34; 'calling': 0.34; 'anything': 0.34; 'latter': 0.34; 'something': 0.35; 'be.': 0.35; 'supposed': 0.35; 'apply': 0.35; '...': 0.36; 'uses': 0.36; 'subject:with': 0.36; 'bound': 0.37; 'class.': 0.37; 'but': 0.37; 'passed': 0.37; 'entry': 0.37; 'think': 0.37; 'could': 0.37; 'steven': 0.38; 'received:org': 0.38; 'itself.': 0.39; 'either': 0.39; 'should': 0.39; 'goes': 0.39; 'called': 0.40; 'subject: (': 0.40; 'to:addr:python.org': 0.40; '2011': 0.61; 'types': 0.61; 'happen': 0.61; 'believe': 0.65; 'below.': 0.66; 'special': 0.68; 'access,': 0.74; 'below:': 0.80; '-0500,': 0.84; 'irrelevant': 0.84; 'method)': 0.84; 'namely': 0.84; 'self:': 0.84; 'supplying': 0.84; 'live.': 0.95; 'treatment': 0.97
X-Injected-Via-Gmane http://gmane.org/
To python-list@python.org
From Terry Reedy <tjreedy@udel.edu>
Subject Re: AttributeError in "with" statement (3.2.2)
Date Wed, 14 Dec 2011 18:13:36 -0500
References <b8092181-c306-40bc-a07a-bb35bc925cf1@18g2000prn.googlegroups.com> <CALFfu7BwozUsp=WB1+66wH9RR1=DQCAprNve7N+LFR2ptGMFWg@mail.gmail.com> <mailman.3626.1323844169.27778.python-list@python.org> <4ee857d4$0$11091$c3e8da3@news.astraweb.com>
Mime-Version 1.0
Content-Type text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding 7bit
X-Gmane-NNTP-Posting-Host pool-74-109-121-73.phlapa.fios.verizon.net
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0) Gecko/20111105 Thunderbird/8.0
In-Reply-To <4ee857d4$0$11091$c3e8da3@news.astraweb.com>
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.12
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <http://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 <http://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
Newsgroups comp.lang.python
Message-ID <mailman.3659.1323904439.27778.python-list@python.org> (permalink)
Lines 107
NNTP-Posting-Host 2001:888:2000:d::a6
X-Trace 1323904439 news.xs4all.nl 6881 [2001:888:2000:d::a6]:33091
X-Complaints-To abuse@xs4all.nl
Xref x330-a1.tempe.blueboxinc.net comp.lang.python:17240

Show key headers only | View raw


On 12/14/2011 3:01 AM, Steven D'Aprano wrote:
> On Wed, 14 Dec 2011 01:29:13 -0500, Terry Reedy wrote:
>
>> To complement what Eric says below: The with statement is looking for an
>> instance *method*, which by definition, is a function attribute of a
>> *class* (the class of the context manager) that takes an instance of the
>> class as its first parameter.
>
> I'm not sure that is correct... I don't think that there is anything "by
> definition" about where methods live.

 From the Python glossary:
"method: A function which is defined inside a class body."

That is actually a bit too narrow, as a function can be added to the 
class after it is defined. But the point then is that it is treated as 
if defined inside the class body.

> Particularly not in Python where
> instance methods can be attributes of the instance itself.

This is access, not definition or actual location. The glossary entry go 
on to say: "If called as an attribute of an instance of that class, the 
method will get the instance object as its first argument (which is 
usually called self)." This does *not* happen if a callable is found in 
the instance-specific dictionary. An instance method is a function 
(callable) attribute of a class that gets special treatment when 
accessed (indirectly) through an instance of that class (or subclass 
thereof).

>>>> class Test(object):
> ...     def method(self):
> ...             print("This method is an attribute of the class.")
> ...
>>>> t = Test()
>>>> t.method()
> This method is an attribute of the class.

The bound method t.method is an instance the class exposed as 
types.MethodType. In other words, isinstance(t.method, types.MethodType) 
== True

>>>> import types
>>>> t.method = types.MethodType(
> ...     lambda self: print(
> ...     "This method is an attribute of the instance."), t)

Calling any old fruit an apple does not make it one.
Calling any old function a method does not make it one.

'types.MethodType' is the exposed name of the class the interpreter uses 
to create bound methods from a method and an instance of the class 
containing the method. I believe the interpreter does an isinstance 
check, but it must do that before calling the class, and not in the 
bound method constructor itself. In any case, a bound method is not a 
method. So the printed statement is not true.

In this case, the result is not really even a bound method, as the 
function argument is not a method, so we cannot even ask if the second 
arg is an instance of the function class container.  MethodType is a 
special case of functools.partial, which was added later. You could have 
used the latter to the same effect. Or you could have used any old 
function that printed the same thing.

There is no relation between the object passed as the second arg of 
MethodType and what you do with the resulting callable. Either 't' could 
be something else. See below.

>>>> t.method()
> This method is an attribute of the instance.

Yes, the callable (which is not a method) is (currently) an attribute of 
the instance. But that is irrelevant to its operation. t.method is just 
a callable, in particular, a pseudo bound method, not a method. It is 
*not* supplying the instance it is called on as the first parameter of 
the callable. The arguemnt (which is not used) has already been 
supplied. These produce the same output:

class B: pass
b = B()
b.method = t.method
b.method()

f = t.method
f()

t.method = lambda:  print("This method is an attribute of the instance.")
t.method()

> So the normal lookup rules that apply to data attributes, namely
> instance, then class, then superclasses, also applies to methods in
> Python.

When you ask the interpreter to resolve a.x, x is just a supposed 
attribute, and the interpreter has no idea what class the result should be.

> But this doesn't apply for special dunder attributes like __exit__, for
> speed reasons.

It does not apply to dunder *methods* because they are reserved names 
defined to be (bound to) methods. So the interpreter knowing that it is 
looking for a method and that methods have to be attributes of classes, 
goes directly to the class.

-- 
Terry Jan Reedy

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

AttributeError in "with" statement (3.2.2) Steve Howell <showell30@yahoo.com> - 2011-12-13 21:42 -0800
  Re: AttributeError in "with" statement (3.2.2) Eric Snow <ericsnowcurrently@gmail.com> - 2011-12-13 23:05 -0700
  Re: AttributeError in "with" statement (3.2.2) Terry Reedy <tjreedy@udel.edu> - 2011-12-14 01:29 -0500
    Re: AttributeError in "with" statement (3.2.2) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-14 08:01 +0000
      Re: AttributeError in "with" statement (3.2.2) 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-14 08:08 -0800
        Re: AttributeError in "with" statement (3.2.2) 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-14 08:28 -0800
      Re: AttributeError in "with" statement (3.2.2) Steve Howell <showell30@yahoo.com> - 2011-12-14 09:16 -0800
      Re: AttributeError in "with" statement (3.2.2) Terry Reedy <tjreedy@udel.edu> - 2011-12-14 18:13 -0500
        Re: AttributeError in "with" statement (3.2.2) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-15 05:01 +0000
          Re: AttributeError in "with" statement (3.2.2) MRAB <python@mrabarnett.plus.com> - 2011-12-15 05:15 +0000
            Re: AttributeError in "with" statement (3.2.2) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-15 07:21 +0000
            Re: AttributeError in "with" statement (3.2.2) Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2011-12-16 09:34 +1300
          Re: AttributeError in "with" statement (3.2.2) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-15 07:47 +0000
          Re: AttributeError in "with" statement (3.2.2) Steve Howell <showell30@yahoo.com> - 2011-12-15 05:35 -0800
            Re: AttributeError in "with" statement (3.2.2) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-16 03:34 +0000
          Re: AttributeError in "with" statement (3.2.2) Terry Reedy <tjreedy@udel.edu> - 2011-12-15 19:39 -0500
            Re: AttributeError in "with" statement (3.2.2) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-16 09:22 +0000
              Re: AttributeError in "with" statement (3.2.2) Terry Reedy <tjreedy@udel.edu> - 2011-12-16 17:05 -0500
                Re: AttributeError in "with" statement (3.2.2) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-17 01:26 +0000
                Re: AttributeError in "with" statement (3.2.2) Terry Reedy <tjreedy@udel.edu> - 2011-12-17 21:09 -0500
              Re: AttributeError in "with" statement (3.2.2) Ethan Furman <ethan@stoneleaf.us> - 2011-12-16 15:26 -0800
                Re: AttributeError in "with" statement (3.2.2) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-17 03:05 +0000
              Re: AttributeError in "with" statement (3.2.2) Ethan Furman <ethan@stoneleaf.us> - 2011-12-16 16:34 -0800
  Re: AttributeError in "with" statement (3.2.2) Peter Otten <__peter__@web.de> - 2011-12-14 11:02 +0100
  Re: AttributeError in "with" statement (3.2.2) Eric Snow <ericsnowcurrently@gmail.com> - 2011-12-14 09:56 -0700
  Re: AttributeError in "with" statement (3.2.2) Lie Ryan <lie.1296@gmail.com> - 2011-12-15 06:14 +1100
  Re: AttributeError in "with" statement (3.2.2) Eric Snow <ericsnowcurrently@gmail.com> - 2011-12-14 12:46 -0700

csiph-web