Why would one use contextlib.suppress
to suppress an exception, instead of try
/except
with a pass
?
There is no difference in the amount of characters between these two methods (if anything, suppress
has more characters), and even though code is often counted in LOC instead of characters, suppress
also seems to be much slower than try
/except
in both cases, when an error is raised and when it's not:
Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) [MSC v.1900 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> from timeit import timeit
>>> # With an error
>>> timeit("""with suppress(ValueError):
x = int('a')""", setup="from contextlib import suppress")
1.9571568971892543
>>> timeit("""try:
x = int('a')
except ValueError:
pass""")
1.0758466499161656
>>> # With no error
>>> timeit("""with suppress(ValueError):
x = int(3)""", setup="from contextlib import suppress")
0.7513525708063895
>>> timeit("""try:
x = int(3)
except ValueError:
pass""")
0.10141028937128027
>>>
To suppress an exception means that we will not handle the exception explicitly and it shouldn't cause the program to terminate. Using the try-except blocks and the pass statement in python, we can suppress the exceptions in python. The pass statement is used as a null statement. When executed, it does nothing.
The except:pass construct essentially silences any and all exceptional conditions that come up while the code covered in the try: block is being run.
Using Try Exceptblock to catch the ZeroDivisionError exception and ignore it. In the above code, we catch the ZeroDivisionError exception and use pass to ignore it. So, when this exception happens, nothing will be thrown and the program will just keep running by ignoring the zero number.
It is two lines less code without sacrificing readability.
It might be especially convenient for nested or consecutive code blocks. Compare:
try:
a()
try:
b()
except B:
pass
except A:
pass
vs.:
with suppress(A):
a()
with suppress(B):
b()
It also allows to express the intent:
with suppress(SpecificError): do_something()
says don't propagate the error if it is raised while doing something
try: do_something() except SpecificError: pass
says do something and don't propagate the error if it is raised
It is less important because most people won't notice the difference.
Conceptually, for me, the contextlib.suppress approach allows me to handle errors that are likely to occur (such as attempting to remove a file that may not actually be there). try/except then becomes a more active handling of 'this should not happen' events (such as a divide by 0 or inability to open a few to which I want to write).
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