Is the following code doing anything wrong with with
statement and exception handling of python3? If no, what is the correct way of writing my expected output?
from contextlib import contextmanager
@contextmanager
def test():
print("Hello")
yield
print("goodbye")
try:
with test():
print("inside test")
raise KeyError
except KeyError:
print("KeyError")
else:
print("else")
finally:
print("finally")
and the output is
Hello
inside test
KeyError
finally
and I expect the output is:
Hello
inside test
goodbye
KeyError
finally
which I believe other people write similarly in the hope that the file would be closed when an exception was raised during the processing of the file.
My python3 version is:
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print(sys.version)
3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609]
The except block lets you handle the error. The else block lets you execute code when there is no error. The finally block lets you execute code, regardless of the result of the try- and except blocks.
When an exception occurs inside a try block, control goes directly to the catch block, so no other code will be executed inside the try block and the value of res will not change. Also when a method throws an exception it does not return anything.
In Python, try-except blocks can be used to catch and respond to one or multiple exceptions. In cases where a process raises more than one possible exception, they can all be handled using a single except clause.
The exception from within the block governed by the with statement is propagated to your generator context manager through generator.throw()
as shown in PEP 343: "Generator Decorator", which raises the exception at the point where the generator was paused. In other words you should wrap the yield
in a try/except or try/finally:
@contextmanager
def test():
print("Hello")
try:
# The block of the with statement executes when the generator yields
yield
finally:
print("goodbye")
To quote the official documentation on the subject:
...If an unhandled exception occurs in the block, it is reraised inside the generator at the point where the yield occurred. Thus, you can use a try…except…finally statement to trap the error (if any), or ensure that some cleanup takes place. If an exception is trapped merely in order to log it or to perform some action (rather than to suppress it entirely), the generator must reraise that exception. Otherwise the generator context manager will indicate to the with statement that the exception has been handled, and execution will resume with the statement immediately following the with statement.
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