Suppose we have the following
def __exit__(self, *exc):
Traceback (most recent call last):
File "./test.py", line 3, in <module>
- The context expression (the expression given in the with_item) is evaluated to obtain a context manager.
- The context manager’sis loaded for later use.
- The context manager’smethod is invoked.
__exit__ is a special method, so Python looks it up on the type. The
module type has no such method, which is why this fails.
See the Special method lookup section of the Python datamodel documentation:
For custom classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary.
Note that this applies to all special methods. For example, if you added a
__repr__ function to a module it'll not be called when printing the module, either.
Python does this to make sure type objects are hashable and representable too; if Python didn't do this then trying to put a class object into a dictionary would fail when a
__hash__ method was defined for that class (as that method would expect an instance to be passed in for