AttributeError in "with" statement (3.2.2)

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Dec 14 03:01:24 EST 2011


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. Particularly not in Python where 
instance methods can be attributes of the instance itself.

>>> 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.
>>>
>>> import types
>>> t.method = types.MethodType(
...     lambda self: print(
...     "This method is an attribute of the instance."), t)
>>> t.method()
This method is an attribute of the instance.


So the normal lookup rules that apply to data attributes, namely 
instance, then class, then superclasses, also applies to methods in 
Python. In languages that don't allow that sort of thing, like Java, you 
need to use convoluted design patterns like Dynamic Proxy to make it 
work. In Python, you just create a method and attach it on the instance.

http://stackoverflow.com/questions/8260740/override-a-method-for-an-
instance-of-a-class

But this doesn't apply for special dunder attributes like __exit__, for 
speed reasons. (For new-style classes only, classic classes have no such 
special casing. This makes automatic delegation a breeze in Python 2 with 
classic classes, and a PITA in Python 3. Boo hiss.)



-- 
Steven



More information about the Python-list mailing list