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, return self
(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:
def __enter__(self):
print 'Entering MyResource'
return self