-
https://www.jb51.net/article/112954.htm
原先的流程:
1234567891011def
crawl_page(url):
pass
def
log_error(url):
pass
url
=
""
try
:
crawl_page(url)
except
:
log_error(url)
改進后的流程:
12345678910attempts
=
0
success
=
False
while
attempts <
3
and
not
success:
try
:
crawl_page(url)
success
=
True
except
:
attempts
+
=
1
if
attempts
=
=
3
:
break
最近發現的新的解決方案:retrying
retrying是一個 Python的重試包,可以用來自動重試一些可能運行失敗的程序段。
retrying
提供一個裝飾器函數retry
,被裝飾的函數就會在運行失敗的條件下重新執行,默認只要一直報錯就會不斷重試。1234567891011import
random
from
retrying
import
retry
@retry
def
do_something_unreliable():
if
random.randint(
0
,
10
) >
1
:
raise
IOError(
"Broken sauce, everything is hosed!!!111one"
)
else
:
return
"Awesome sauce!"
print
do_something_unreliable()
retry還可以接受一些參數,這個從源碼中Retrying類的初始化函數可以看到可選的參數:
stop_max_attempt_number
:用來設定最大的嘗試次數,超過該次數就停止重試-
stop_max_delay
:比如設置成10000,那么從被裝飾的函數開始執行的時間點開始,到函數成功運行結束或者失敗報錯中止的時間點,只要這段時間超過10秒,函數就不會再執行了 wait_fixed
:設置在兩次retrying
之間的停留時間wait_random_min和wait_random_max
:用隨機的方式產生兩次retrying
之間的停留時間wait_exponential_multiplier和wait_exponential_max
:以指數的形式產生兩次retrying
之間的停留時間,產生的值為2^previous_attempt_number * wait_exponential_multiplier
,previous_attempt_number
是前面已經retry
的次數,如果產生的這個值超過了wait_exponential_max
的大小,那么之后兩個retrying之間的停留值都為wait_exponential_max
。這個設計迎合了exponential backoff
算法,可以減輕阻塞的情況。- 我們可以指定要在出現哪些異常的時候再去retry,這個要用
retry_on_exception
傳入一個函數對象:
1234567def
retry_if_io_error(exception):
return
isinstance
(exception, IOError)
@retry
(retry_on_exception
=
retry_if_io_error)
def
read_a_file():
with
open
(
"file"
,
"r"
) as f:
return
f.read()
在執行
read_a_file
函數的過程中,如果報出異常,那么這個異常會以形參exception
傳入retry_if_io_error
函數中,如果exception
是IOError
那么就進行retry
,如果不是就停止運行並拋出異常。我們還可以指定要在得到哪些結果的時候去
retry
,這個要用retry_on_result
傳入一個函數對象:123456def
retry_if_result_none(result):
return
result
is
None
@retry
(retry_on_result
=
retry_if_result_none)
def
get_result():
return
None
在執行
get_result
成功后,會將函數的返回值通過形參result
的形式傳入retry_if_result_none
函數中,如果返回值是None
那么就進行retry
,否則就結束並返回函數值。總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。