One-Line Exception Handling
Solution 1
It is not possible to do a one-line exception-handling statement in python. One could write a function to do this.
def safe_execute(default, exception, function, *args):
try:
return function(*args)
except exception:
return default
Example usage:
from json import loads
safe_execute("Oh no, explosions occurred!", TypeError, loads, None)
# Returns "Oh no, explosions occurred!"
safe_execute("Huh?", TypeError, int, "10")
#Returns 10
Multiple arguments are supported
from operator import div
safe_execute(
"Divsion by zero is invalid.",
ZeroDivisionError,
div, 1, 0
)
# Returns "Divsion by zero is invalid."
safe_execute(
"Divsion by zero is invalid.",
ZeroDivisionError,
div, 1, 1
)
# Returns 1.
The error-catching process may still be interrupted:
from time import sleep
safe_execute(
"Panic!",
Exception,
sleep, 8
)
# Ctrl-c will raise a KeyboardInterrupt
from sys import exit
safe_execute("Failed to exit!", Exception, exit)
# Exits the Python interpreter
If this behavior is undesired, use BaseException
:
from time import sleep
safe_execute("interrupted",
BaseException,
sleep, 8)
#Pressing Ctrl-c will return "interrupted"
from sys import exit
safe_execute("Naughty little program!",
BaseException,
exit)
#Returns "Naughty little program!"
Solution 2
It is possible in one line using exec:
parse_float = lambda x, y=exec("def f(s):\n try:\n return float(s)\n except: return None"): f(x)
Solution 3
You can use contextlib
to suppress
exceptions. If you like to live dangerously you could suppress BaseException
, which would suppress all builtin exceptions (probably a bad idea). Or you could pick a safe one relevant to your code, like TypeError
.
examples:
from contextlib import suppress
# this will execute right along
with suppress(BaseException): fhasldjkfhsa345315
# even raising an Exception will fly just fine
with suppress(BaseException): raise NameError
# correct code will execute just fine
x=5
with suppress(BaseException): x+=2
print(x) # prints 7
# and in your example:
from json import loads
pleasure = suppress(TypeError) # so each line rolls off the tongue :)
with pleasure: result = loads('{"value": True}')
print(result) # prints {'value': True}
with pleasure: result = loads(None)
print(result) # prints {'value': True} because result never changed
Related videos on Youtube
2Cubed
Python fanatic, night-owl, and lover of beautiful code. "Don't undertake a project unless it is manifestly important and nearly impossible." -Edwin Land
Updated on December 27, 2021Comments
-
2Cubed over 2 years
In Python, it is possible to use one-liners to set values with special conditions (such as defaults or conditions) in a simple, intuitive way.
result = 0 or "Does not exist." # "Does not exist." result = "Found user!" if user in user_list else "User not found."
Is it possible to write a similar statement that catches exceptions?
from json import loads result = loads('{"value": true}') or "Oh no, explosions occurred!" # {'value': True} result = loads(None) or "Oh no, explosions occurred!" # "Oh no, explosions occurred!" is desired, but a TypeError is raised.
-
TigerhawkT3 about 8 yearsWhy not put the standard
try..except
into the function? -
2Cubed about 8 years@Slayer Interestingly, Python will actually use a string (or any other object, in fact) as an "alternate" for
or
.0 or "Does not exist."
will return"Does not exist."
. (I have tested it.) -
2Cubed about 8 years@TigerhawkT3 I do not have access to the internals of the
divide_one_by
function - assume that it is defined in a separate module which I am using as a dependency. -
Jongware about 8 years@2Cubed: no reason to be surprised.
0 OR x
evaluates tox
for all values ofx
, except0
itself. -
TigerhawkT3 about 8 yearsSo write a wrapper function, perhaps?
-
TigerhawkT3 about 8 years@RadLexus - It evaluates to
x
whenx
is0
as well. It'll simply be0
. -
Jongware about 8 years@TigerhawkT3: does that not evaluate to
False
instead? (Testing..) Oh I see it indeed does not. :)print 0 or False
does, though, proving my point on anything forx
. Even 0. -
2Cubed about 8 years@TigerhawkT3: Good idea. Thanks!
-
chepner about 8 yearsThere is a PEP to add something like this, but it hasn't been accepted yet.
-
Alexey Shrub over 4 yearssuppress maybe useful for some cases stackoverflow.com/a/52020518/8583496
-
-
thepunitsingh almost 5 yearsYou have a great suggestion. I am trying to create a similar workaround for my problem but the code is unable to work. I have detailed the problem at stackoverflow.com/q/56916092/6701627. I will be thankful if you could check the problem and provide some suggestion on it.
-
sp4c38 almost 3 yearsyeah but that's so horribly unpythonic... it's like putting an image of a website on a website instead of the actual html itself