我想在同一个任务中尝试多种不同的方法,每次方法失败时都会捕获异常。我知道如果尝试失败将引发的异常(并且每次尝试可能会有所不同)。在最后一次尝试之后,我想优雅地放弃并继续前进。
我目前通过嵌套的try
/ except
子句执行此操作:
try:
first_approach()
except Exception1:
try:
second_approach()
except Exception2:
try:
third_approach()
except:
give_up()
except Exception2:
try:
third_approach()
except:
give_up()
但这对我来说很糟糕,因为third_approach()
会重复。我在the Python docs中看不到任何帮助。
那么我怎样才能展平这个丑陋的嵌套代码?
例如,假设我试图读取CSV文件列表,而不事先知道它们的编码。
某些CSV文件甚至可能是通过文件扩展名伪装成CSV的XLS文件。
因此,我想尝试一些不同的编码,如果这些编码都不起作用,请尝试将文件读作excel。
for f in files:
try:
read_csv(f, encoding='utf-8')
except UnicodeDecodeError:
try:
read_csv(f, encoding='latin1')
except NotCsvError:
try:
read_excel(f)
except:
give_up()
except NotCsvError:
try:
read_excel(f)
except:
give_up()
答案 0 :(得分:7)
您可以使用for
/ else
循环遍历您的方法功能。
else
子句仅在for
语句未终止break
时才会运行。
approaches = ((first_approach, [arg1, arg2, ...], {'kwarg1':kwarg1, 'kwarg2':kwarg2, ...}, (Approach1Exception1, Approach1Exception2, ...)),
(second_approach, ..., ..., ...),
(third_approach, ..., ..., ...),
...)
for approach, args, kwargs, exceptions in approaches:
try:
approach(*args, **kwargs)
break
except exceptions:
pass
else:
give_up()
答案 1 :(得分:2)
仍然嵌套,但DRYer:
for f in files:
try:
try:
read_csv(f, encoding='utf-8')
except UnicodeDecodeError:
read_csv(f, encoding='latin1')
except NotCsvError:
try:
read_excel(f)
except:
give_up()
在外部块中,首先尝试使用UTF-8,然后尝试使用Latin-1,如果它失败并出现UnicodeDecodeError。如果其中失败并带有NotCsvError,则控制权将传递给外部except
子句。这利用了read_excel
并不关心您之前尝试过哪种编码的事实。
答案 2 :(得分:0)
虽然我的解决方案仍然存在三个级别的嵌套,但尝试不同方法的逻辑已经趋于平缓:
ex = None
while True:
try:
if ex is None:
first_approach()
elif ex is Exception1:
second_approach()
elif ex is Exception2:
third_approach()
else:
give_up()
break
except:
ex = sys.exc_info()[0]
但请注意,此代码与您的版本不完全等效。例如,如果third_approach()
引发Exception2
,它将最终成为无限循环。