I have a problem with my code in the try block. To make it easy this is my code:
try:
code a
code b #if b fails, it should ignore, and go to c.
code c #if c fails, go to d
code d
except:
pass
Is something like this possible?
I have a problem with my code in the try block. To make it easy this is my code:
try:
code a
code b #if b fails, it should ignore, and go to c.
code c #if c fails, go to d
code d
except:
pass
Is something like this possible?
You'll have to make this separate try
blocks:
try:
code a
except ExplicitException:
pass
try:
code b
except ExplicitException:
try:
code c
except ExplicitException:
try:
code d
except ExplicitException:
pass
This assumes you want to run code c
only if code b
failed.
If you need to run code c
regardless, you need to put the try
blocks one after the other:
try:
code a
except ExplicitException:
pass
try:
code b
except ExplicitException:
pass
try:
code c
except ExplicitException:
pass
try:
code d
except ExplicitException:
pass
I'm using except ExplicitException
here because it is never a good practice to blindly ignore all exceptions. You'll be ignoring MemoryError
, KeyboardInterrupt
and SystemExit
as well otherwise, which you normally do not want to ignore or intercept without some kind of re-raise or conscious reason for handling those.
You can use fuckit module.
Wrap your code in a function with @fuckit
decorator:
@fuckit
def func():
code a
code b #if b fails, it should ignore, and go to c.
code c #if c fails, go to d
code d
Extract (refactor) your statements. And use the magic of and
and or
to decide when to short-circuit.
def a():
try: # a code
except: pass # or raise
else: return True
def b():
try: # b code
except: pass # or raise
else: return True
def c():
try: # c code
except: pass # or raise
else: return True
def d():
try: # d code
except: pass # or raise
else: return True
def main():
try:
a() and b() or c() or d()
except:
pass
b
fails (raises an exception), c
will not be executed, nor will d
. –
Greathearted pass
too..... edited it, better? –
Henriettehenriha c
even if b
succeeds. –
Greathearted except: pass ... else: return True
is an obscure way of implicitly saying except: return None ... else: return True
. Better to be explicit. –
Timoteo If you don't want to chain (a huge number of) try-except clauses, you may try your codes in a loop and break upon 1st success.
Example with codes which can be put into functions:
for code in (
lambda: a / b,
lambda: a / (b + 1),
lambda: a / (b + 2),
):
try: print(code())
except Exception as ev: continue
break
else:
print("it failed: %s" % ev)
Example with arbitrary codes (statements) directly in the current scope:
for i in 2, 1, 0:
try:
if i == 2: print(a / b)
elif i == 1: print(a / (b + 1))
elif i == 0: print(a / (b + 2))
break
except Exception as ev:
if i:
continue
print("it failed: %s" % ev)
You could try a for loop
for func,args,kwargs in zip([a,b,c,d],
[args_a,args_b,args_c,args_d],
[kw_a,kw_b,kw_c,kw_d]):
try:
func(*args, **kwargs)
break
except:
pass
This way you can loop as many functions as you want without making the code look ugly
Lets say each code is a function and its already written then the following can be used to iter through your coding list and exit the for-loop when a function is executed without error using the "break".
def a(): code a
def b(): code b
def c(): code c
def d(): code d
for func in [a, b, c, d]: # change list order to change execution order.
try:
func()
break
except Exception as err:
print (err)
continue
I used "Exception " here so you can see any error printed. Turn-off the print if you know what to expect and you're not caring (e.g. in case the code returns two or three list items (i,j = msg.split('.')).
try
–
Denude I ran into this problem, but then it was doing the things in a loop which turned it into a simple case of issueing the continue
command if successful. I think one could reuse that technique if not in a loop, at least in some cases:
while True:
try:
code_a
break
except:
pass
try:
code_b
break
except:
pass
etc
raise NothingSuccessfulError
I use a different way, with a new variable:
continue_execution = True
try:
command1
continue_execution = False
except:
pass
if continue_execution:
try:
command2
except:
command3
to add more commands you just have to add more expressions like this:
try:
commandn
continue_execution = False
except:
pass
Building on kxr's answer (not enough rep to comment) you can use For/Else (see docs) to avoid checking the i
value. The else
clause only executes when the for
finishes normally, so it gets skipped when the break
executes
for i in 2, 1, 0:
try:
if i == 2: print(a / b)
elif i == 1: print(a / (b + 1))
elif i == 0: print(a / (b + 2))
break
except Exception as ev:
continue
else:
print("it failed: %s" % ev)
Like Elazar suggested: "I think a decorator would fit here."
# decorator
def test(func):
def inner(*args, **kwargs):
try:
func(*args, **kwargs)
except: pass
return inner
# code blocks as functions
@test
def code_a(x):
print(1/x)
@test
def code_b(x):
print(1/x)
@test
def code_c(x):
print(1/x)
@test
def code_d(x):
print(1/x)
# call functions
code_a(0)
code_b(1)
code_c(0)
code_c(4)
output:
1.0
0.25
assuming each code block returns non-null value. (where you should design it to be)
val = None
try:
val = func_a()
except (AErr, ...):
expt_a() # e.g. print('bad a')
try:
val = val or func_b()
except (BErr, ...):
expt_b()
try:
val = val or func_c()
except (CErr, ...):
expt_c()
if there are plenty of these structures, further simplify as
func_errs_expt_list = [
[func_a, (AErr,...), expt_a],
[func_b, (BErr,...), expt_b],
[func_c, (CErr,...), expt_c],
...
]
val = None
for func, errs, expt in func_errs_expt_list:
try:
val = val or func(*args, **kwargs)
except errs:
expt(*args, **kwargs)
introducing oo to prettify elements is possible
class BaseExceptionSafeBlock:
@staticmethod
def _try(*args, **kwargs):
raise NotImplementedError('return non-null')
@staticmethod
def _expected_errors(*args, **kwargs):
return tuple() # overridable
@staticmethod
def _except(e, *args, **kwargs):
pass # overridable
@classmethod
def try(cls, *args, **kwargs):
try:
return cls._try(*args, **kwargs)
except cls._expected_errors(*args, **kwargs) as e:
cls._except(e, *args, **kwargs):
return None
class ABlock(BaseExceptionSafeBlock):
@staticmethod
def _try(*args, **kwargs):
# do something and return it
...
def execute(blocks, *args, **kwargs):
for block in blocks:
res = block.try(*args, **kwargs)
if res is not None:
return res
return None
val = execute([ABlock, ...], *args, **kwargs)
© 2022 - 2025 — McMap. All rights reserved.
code c
to be executed only when code b raises an exception? – Greatheartedtry
block is not there to suppress exceptions across all code executed. It'll let you catch the exception when it happens, but the rest of the block is never executed. – Greathearted