iT邦幫忙

0

Python 學習筆記_裝飾器(decorator) 與重試(retry)

  • 分享至 

  • xImage
  •  

這篇文章主要是在紀錄 python decorator 的學習過程,
有錯或是更好的寫法的話,歡迎留言討論!!

一、裝飾器 Decorator

裝飾器可以幫助我們更加精簡我們的程式碼,舉凡 Flask、FastAPI 等 module 都有使用
更加詳細的介紹可以參考 這個網址

二、簡單範例

def demo_decorator(callback):
    def add():
        print("測試裝飾器")
        
        # 測試用內容,會印出累加
        tmp = 0
        for i in range(10):
            tmp += i
        print(tmp)
        
        # 呼叫 callback 也就是帶有裝飾器的函式本身
        callback()
    
    # 規定要回傳裝飾器內的函式
    return add


@demo_decorator
def demo_main_function():
    print("測試函式")


if __name__ == '__main__':
    demo_main_function()
  • 執行順序:
  1. 當被執行的函示帶有裝飾器的時候,會先執行裝飾器中的程式
  2. 進入該裝飾器內後,會先印出 "測試裝飾器"
  3. 接著會進行 for 迴圈的累加
  4. 最後回呼原本的函式執行原有函式的內容,印出 "測試函式"

三、retry decorator

在網路爬蟲當中,我們常常會遇到需要重試請求的情況,碰到這種情況,我們可以利用 decorator 進行重試

(一)、建立裝飾器

import requests


def retry_decorator(callback):
    def retry(url, retry_time):
        recoder = 0
        while recoder < retry_time:
            try:
                return callback(url)
            except requests.exceptions.RequestException:
                print("請求錯誤")
                recoder += 1
    return retry

(二)、建立函式

@retry_decorator
def demo_main_function(url):
    res = requests.get(url)
    print(res.status_code)

(三)、呼叫以及解釋

if __name__ == '__main__':
    # correct url
    demo_main_function("https://google.com.tw", 3)
    print("-------------------")
    # wrong url
    demo_main_function("https://test.test.test", 3)
  • output:
C:\Users\nick\Desktop\deacorator_testt\venv\Scripts\python.exe C:/Users/nick/Desktop/deacorator_testt/main.py
200
-------------------
請求錯誤
請求錯誤
請求錯誤

Process finished with exit code 0
  • 解釋:
  1. 當我們實際在呼叫 demo_main_function 的時候,
    實際上是在呼叫 retry_decorator 當中的 retry function,
    因此可以看到我們必須傳入的參數是兩個,而不是 demo_main_function 當中所定義的一個
  2. 將參數傳入後,decorator 會開始記錄重試的次數,並且利用 try except 來呼叫 demo_main_function,
    使程式不會中斷,並於發生錯誤後累加 recoder 的值,直到重試次數達上限
  3. 利用正確以及不正確的網址各一個來實際測試 decorator 的效用,可以發現錯誤的部分會如預期重試我們想要他重試的次數

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言