I’m experimenting with Python’s with statements, and I’ve found that in the following code listing my __init__ method gets called twice, while my __exit__ method gets called once. This presumably means that there will be a resource leak if this code did anything useful.
class MyResource:
def __enter__(self):
print 'Entering MyResource'
return MyResource()
def __exit__(self, exc_type, exc_value, traceback):
print 'Cleaning up MyResource'
def __init__(self):
print 'Constructing MyResource'
def some_function(self):
print 'Some function'
def main():
with MyResource() as r:
r.some_function()
if __name__=='__main__':
main()
This is the program’s output:
Constructing MyResource
Entering MyResource
Constructing MyResource
Some function
Cleaning up MyResource
I’m guessing it’s because I’m doing something wrong in the with statement, effectively calling the constructor manually. How do I correct this?
You shouldn’t return a new instance from
__enter__. Instead, returnself(the instance for which__enter__is being called. That’s why__init__()is called twice — you call it twice, once in your with statement, once in__enter__(). Here’s a correct version: