[英]How to repeat something upon exception in python?
在python中導致異常之后重復某些事情的最優雅方法是什么?
我有這樣的東西[偽代碼作為例子]:
try:
do_some_database_stuff()
except DatabaseTimeoutException:
reconnect_to_database()
do_some_database_stuff() # just do it again
但想象一下,如果我沒有一個很好的功能,而是很多代碼。 重復的代碼不是很好。
所以我認為這稍微好一些:
while True:
try:
do_some_database_stuff()
break
except DatabaseTimeoutException:
reconnect_to_database()
如果異常確實解決了問題,那就足夠了。 如果不是,我需要一個計數器來防止無限循環:
i = 0
while i < 5:
try:
do_some_database_stuff()
break
except DatabaseTimeoutException:
reconnect_to_database()
i += 1
但后來我真的不知道它是否有效,所以它也是:
while i <= 5:
try:
do_some_database_stuff()
break
except DatabaseTimeoutException:
if i != 5:
reconnect_to_database()
else:
raise DatabaseTimeoutException
i += 1
你可以看到它開始變得非常混亂。
表達這種邏輯的最優雅方式是什么?
您可以使用“ for-else ”循環:
for ii in range(5):
try:
do_some_database_stuff()
break
except DatabaseTimeoutException:
reconnect_to_database()
else:
raise DatabaseTimeoutException
或者,沒有:
for ii in range(5):
try:
do_some_database_stuff()
break
except DatabaseTimeoutException:
if ii == 4:
raise
reconnect_to_database()
我個人不是for-else構造的粉絲。 我不認為它是直觀的。 我第一次閱讀它時,我認為這意味着“為循環(...)做,如果迭代是空的那么......”。
您應該將代碼放在函數中。 如果do_some_database_stuff()
成功完成,那么您可以使用return語句從函數中提前返回。
例如。
def try_to_do_some_database_stuff():
for i in range(num_times):
try:
return do_some_database_stuff()
except DatabaseTimeoutException:
reconnect_to_database()
raise DatabaseTimeoutException
如果你發現自己使用這個構造很多,那么你可以使它更通用。
def try_to_do(func, catch, times=2, on_exception=None):
for i in range(times):
try:
return func()
except catch:
if on_exception:
on_exception()
raise catch
try_to_do(do_some_database_stuff, catch=DatabaseTimeoutException, times=5,
on_exception=reconnect_to_database)
如果需要將參數傳遞給函數,可以使用functools.partial
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.