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