Assume you have a class with defined __enter__
and __exit__
methods like so:
class MyClass:
def f(self):
raise Exception
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
pass
If an exception is raised inside the with
block, like so:
with MyClass() as ins:
ins.f()
The __exit__
method will be implicitly called, which is very nice.
However if your class is like this:
class MyClass:
def __init__(self):
self.f()
def f(self):
raise Exception
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
pass
And you instantiate it like so:
with MyClass() as ins:
pass
When the exception is raised inside the __init__
method, __enter__
has yet to be called, and __exit__
goes uncalled as well, which is not so nice. What is the best way to remedy this?
Obviously you cannot use a class that cannot be initiated as a context manager, so you have to create the instance before using it in the with block.
For example:
try:
ins = MyClass()
except Exception as e:
print "Cant initiate MyClass"
else:
with ins:
pass
You can add extra resources by passing them to the Class instead of creating them during initiation:
with spawnResource() as res, MyClass(res) as y:
print x,y
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With