<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## Python 裝飾器需要了解的知識 * 閉包 * 如何將函數做為一階參數 * 變量參數 * 參數解包 * Python 加載源代碼的細節 ## 分析、日志與手段 對于大型應用, 我們常常需要**記錄應用的狀態**,以及測量不同活動的數量。通過將這些特別的事件包裝到函數或方法中,裝飾器可以很輕松地滿足這些需求,同時保證代碼的可讀性。 ``` from myapp.log import logger def log_order_event(func): def wrapper(*args, **kwargs): logger.info("Ordering: ", func.__name__) order = func(*args, **kwargs) logger.debug("Order result: ", order.result) return order return wrapper @log_order_event def order_pizza(*toppings): # let's get some pizza! ``` 這個方法也可以用來記數或者記錄其它某些指標。 ## 驗證以及運行時檢查 Python 是一種強類型語言,但是變量的類型卻是動態變化的。雖然這會帶來很多好處,但是同時這也意味著更容易引入 bug。對于靜態語言,例如 Java, 這些 bug 在編譯階段就可以被發現。因而,你可能希望在對傳入或返回的數據進行一些自定義的的檢查。裝飾器就可以讓你非常容易地實現這個需求,并一次性將其應用到多個函數上。 想像一下:你有許多函數,每個函數返回一個字典類型,該字典包含一個“summary ”域。這個域的值不能超過 80 個字符的長度。如果違反這個要求,那就是一個錯誤。下面這個裝飾器會在錯誤發生時拋出 ValueError 異常: ``` def validate_summary(func): def wrapper(*args, **kwargs): data = func(*args, **kwargs) if len(data["summary"]) > 80: raise ValueError("Summary too long") return data return wrapper @validate_summary def fetch_customer_data(): # ... @validate_summary def query_orders(criteria): # ... @validate_summary def create_invoice(params): # ... ``` ## 創建框架 一旦你掌握了如何寫裝飾器,你就能夠從其使用的簡單的語法中獲益頗豐,你可以為語言添加新的語義使其使用更加簡單。接下來最棒的就是你可以自己擴展 Python 語法。 事實上,很多開源框架都是使用的這樣的方式。 Web 應用框架 Flask 就是使用裝飾器將不同 URL 路由到不同處理 HTTP 請求函數的: ``` # For a RESTful todo-list API. @app.route("/tasks/", methods=["GET"]) def get_all_tasks(): tasks = app.store.get_all_tasks() return make_response(json.dumps(tasks), 200) @app.route("/tasks/", methods=["POST"]) def create_task(): payload = request.get_json(force=True) task_id = app.store.create_task( summary = payload["summary"], description = payload["description"], ) task_info = {"id": task_id} return make_response(json.dumps(task_info), 201) @app.route("/tasks/<int:task_id>/") def task_details(task_id): task_info = app.store.task_details(task_id) if task_info is None: return make_response("", 404) return json.dumps(task_info) ``` 這里有一個全局對象 app,此對象有一個 route 方法。此 route 函數返回一個用于修飾請求處理函數的裝飾器。這背后的處理是非常復雜的,但是對于使用 Flask 的程序員來說,所有復雜的東西都被隱藏起來了。 在平時使用 Python 過程中,我們也會這樣使用裝飾器。例如,所有的對象都依賴于類方法與屬性裝飾器: ``` class WeatherSimulation: def __init__(self, **params): self.params = params @classmethod def for_winter(cls, **other_params): params = {'month': 'Jan', 'temp': '0'} params.update(other_params) return cls(**params) @property def progress(self): return self.completed_iterations() / self.total_iterations() ``` 這個類有三個不同的 def 語句,但是每一個的語義都是不同的: 構造器是一個簡單的方法 for_winter 是一個類方法 progress 是一個只讀的動態屬性 @classmethod 裝飾器與 @property 裝飾器可以讓我們在平時使用過程中非常方便地擴展 Python 對象的語義。 ## 復用不能復用的代碼 Python 提供了非常強大的工具以將代碼包裝成易復用的形式,這些工具包括:函數、函數式編程的支持以及一切皆對象的思想。然而,還是存在某些代碼并不能通過使用這些工具進行復用。 假設有一個古怪的 API。你可以通過 HTTP 發送 JSON 格式的請求,它 99.9% 的情況下都是正確工作的。但是,小部分請求會返回服務器內部錯誤的結果。這時候,你需要重新發送請求。在這種情況下,你需要實現重試邏輯,像這樣: ``` resp = None while True: resp = make_api_call() if resp.status_code == 500 and tries < MAX_TRIES: tries += 1 continue break process_response(resp) ``` 現在假設你的代碼庫中有很都地方都進行調用了函數 make_api_call,那么是不是需要在每個調用的地方都實現這個 loop 循環呢?是不是每次添加一次調用都要實現一遍這個循環呢?這種模式能難有一個樣板代碼,除非你使用裝飾器,那么這就變得非常簡單了: ``` def retry(func): def retried_func(*args, **kwargs): MAX_TRIES = 3 tries = 0 while True: resp = func(*args, **kwargs) if resp.status_code == 500 and tries < MAX_TRIES: tries += 1 continue break return resp return retried_func @retry def make_api_call(): # .... ``` ## 讓你的事業騰飛 剛開始寫裝飾器時可能不是那么容易。雖然這并不像造火箭那么難,但你也需要花費一些時間去學習,掌握其中的奧秘。大部分程序都能夠掌握。當你成為團隊里面能把裝飾器寫得很好并且能解決真正的問題的人時,此時其它開發者都會使用你開發的這些裝飾器。因為一旦最難的部分,也就是實現裝飾器完成后,使用裝飾器是非常容易的。這可以極大的放大你所寫代碼的正面影響,這會讓你成為團隊的英雄。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看