在編寫python**進行自動化測試、網路爬蟲或者其他與網路相關的動作的時候,由於網路影響會容易失敗,而這種失敗並不是我們需要去處理的。那麼這種時候最好的辦法就是失敗後重試幾次,以避免網路的間斷性影響。
如果我們正常編寫**的話,可能需要 try…except ,但是這種寫法很麻煩,能實現的效果也很單一。這裡介紹乙個 python 庫retrying
,專門用來對丟擲異常的函式或者方法進行重試。
通過retrying
你能幹什麼:
那接下來我們看看用法,首先你需要安裝這個庫:
pip install retrying
簡單的示例,我們寫乙個函式,其中有乙個變數 a 從 1 到 2 中隨機取乙個, 當 a 為 1 的時候就丟擲異常,我們嘗試在丟擲異常時會不會重試:
import random
defdemo()
: a = random.randint(1,
2)print
(a)# => 先列印,好看效果
if a ==1:
raise
# 為1時丟擲異常
這個函式有 50% 的概率會丟擲錯誤,你可以先試試。不過如果你運氣好的話。。。
好,接下來,我們加上 retrying :
from retrying import retry # => 引入retry裝飾器
import random
@retry(
)# => 裝飾你想重試的函式,注意這裡有括號
defdemo()
: a = random.randint(1,
2)print
(a)# => 先列印,好看效果
if a ==1:
raise
# 為1時丟擲異常
demo(
)# => 執行這個可能報錯的函式
執行幾次看看,是不是當列印 a 為 1 的時候會直到 a 為 2 為止?也就意味著@rery()
處理了異常並重試。
也許你不滿足於讓它預設重試,那麼我們來看看更多的函式。
stop_max_attempt_number
最大重試次數,預設為5次
設定乙個最大重試次數,超過這個次數會停止重試,並把異常丟擲來。按照你的需要設定吧,一般不要太多就行。或者你也可以不設,預設為 5 次,不過前提時你修復了下面的bug。
import random
from retrying import retry
@retry(stop_max_attempt_number=3)
defdemo()
: a = random.randint(1,
2)print
(a, end=
" ")
# 為了排版,列印橫排
if a !=3:
# => 這裡我們改為會始終拋異常的情況,不可能取到3
raise
demo(
)## 1 1 1
## runtimeerror: no active exception to reraise
我們可以看到,執行 3 次都報錯後,第 3 次執行的異常就丟擲了。
這裡源**有個 bug,如果不設這個引數會無限重試(如果你的異常不會中止就時死迴圈)。我們來修復這個 bug ?:
開啟python安裝目錄\lib\site-packages\retrying.py
,找到第87
行
if stop_max_attempt_number is
notnone
:# 改為
if self._stop_max_attempt_number is
notnone
:
wait_fixed
重試的間隔時間
當函式丟擲異常後,下一次重試會間隔wait_fixed
設定的時間。預設是 1000 毫秒(1秒),你可以通過這個引數修改這個預設值。
wait_random_min
和wait_random_max
用來設定隨機的間隔時間
wait_random_min 和 wait_random_max 搭配起來設定預設的隨機等待時間,預設是 0 ~ 1000 毫秒之間隨機等待。
wait_incrementing_increment
每重試一次,持續增加等待時間
預設是 100 毫秒 ,每重試一次,等待時常就會增加 100 毫秒。
stop_max_delay
最長重試延遲時間,單位毫秒
這個不是重試間隔時間,這是函式執行 + 重試結束的整體時間。比如stop_max_delay=2000
也就是說該函式從執行到重試結束為止的時間為 2000 毫秒,超過就結束重試並丟擲異常。如果你的函式執行時間已經超過 stop_max_delay 時間,就並不會重試。
import time
import random
from retrying import retry
@retry(stop_max_delay=
2000
)# => 設定了最大的重試時間
defdemo()
: a = random.randint(1,
2)print
(a, end=
" ")
time.sleep(1)
# => 這裡等待了兩秒
if a !=3:
raise
demo(
)## 1 2
## runtimeerror: no active exception to reraise
retry_on_result
:指定乙個函式,如果指定的函式返回true,則重試,否則丟擲異常退出。
import random
from retrying import retry
deffun()
:# 處理**
return
true
# => 返回true
@retry(retry_on_result=fun)
# 指定函式,如果fun返回true則重試,否則不重試
defdemo()
: a = random.randint(1,
2)print
(a, end=
" ")
if a !=3:
raise
demo(
)
shop_func
:指定被裝飾函式出錯後,會執行的函式,執行該函式後在來重試被裝飾的函式。注意,該函式必須要有兩個引數(attempts, delay)。用來當丟擲異常後,需要做一些處理的時候。
a = random.randint(1,
2)deffun
(attempts, delay)
:global a
a =3print
('待測函式'
)@retry(stop_func=fun)
defdemo()
:print
(a, end=
" ")
time.sleep(1)
if a !=3:
raise
demo(
)
python中的重試
安裝 pip install retrying retry 裝飾器會對函式不斷的重試 預設無限重試 retry def pick one print pick t random.randint 0,2 print t if t 1 raise exception 1 is not picked if...
Python的重試模組
我們寫 的時候,經常會用到重試,如果出錯了,或者出現了其他的問題,就重試一次或者n次,自己寫實現起來比較複雜,用retrying模組就可以很容易的解決了。1 pip install retrying 安裝 下面是幾個重試的例子,直接看 import requests from retrying im...
Oracle中job執行出錯後重試機制
1 每次重試時間都是遞增的,第一次2分鐘,4分鐘,8分鐘,16分鐘 依此類推。2 當超過1440分鐘,也就是24小時的時候,固定的重試時間為1天。3 超過16次重試後,job 就會被標記為broken next date 為4000 1 1,也就是不再進行job重試。4 oracle資料庫重試的時間...