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 -- http://mail.python.org/mailman/listinfo/python-list