<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 裝飾器 > 原文: [https://www.programiz.com/python-programming/decorator](https://www.programiz.com/python-programming/decorator) #### 裝飾器接受一個函數,添加一些功能并返回它。 在本教程中,您將學習如何創建裝飾器以及為什么要使用它。 ## Python 中的裝飾器 Python 有一個有趣的函數,稱為**裝飾器**,可為現有代碼添加功能。 這也稱為**元編程**,因為程序的一部分試圖在編譯時修改程序的另一部分。 * * * ## 學習裝飾器的先決條件 為了了解裝飾器,我們必須首先了解 Python 的一些基本知識。 我們必須對以下事實感到滿意:Python 中的所有內容(是!甚至是類)都是[對象](/python-programming/class)。 我們定義的名稱只是綁定到這些對象的標識符。 [函數](/python-programming/function)也不例外,它們也是對象(帶有屬性)。 各種不同的名稱可以綁定到同一函數對象。 這是一個例子。 ```py def first(msg): print(msg) first("Hello") second = first second("Hello") ``` **輸出** ```py Hello Hello ``` 當您運行代碼時,兩個函數`first`和`second`給出相同的輸出。 在這里,名稱`first`和`second`指的是同一函數對象。 現在事情開始變得怪異了。 可以將函數作為參數傳遞給另一個函數。 如果您在 Python 中使用過`map`,`filter`和`reduce`之類的函數,那么您已經知道這一點。 將其他函數作為參數的此類函數也稱為**高階函數**。 這是這種函數的一個例子。 ```py def inc(x): return x + 1 def dec(x): return x - 1 def operate(func, x): result = func(x) return result ``` 我們調用函數如下。 ```py >>> operate(inc,3) 4 >>> operate(dec,3) 2 ``` 此外,一個函數可以返回另一個函數。 ```py def is_called(): def is_returned(): print("Hello") return is_returned new = is_called() # Outputs "Hello" new() ``` **輸出**: ```py Hello ``` 在這里,`is_returned()`是一個嵌套函數,每次調用`is_called()`時都會定義并返回該函數。 最后,我們必須了解 Python 中的 C [losures。](/python-programming/closure) * * * ## 回到裝飾器 函數和方法被稱為**可調用**,因為它們可以被調用。 實際上,任何實現特殊`__call__()`方法的對象都稱為可調用對象。 因此,從最基本的意義上講,裝飾器是可調用的,可返回可調用的。 基本上,裝飾器接受一個函數,添加一些功能并返回它。 ```py def make_pretty(func): def inner(): print("I got decorated") func() return inner def ordinary(): print("I am ordinary") ``` 在 shell 中運行以下代碼時, ```py >>> ordinary() I am ordinary >>> # let's decorate this ordinary function >>> pretty = make_pretty(ordinary) >>> pretty() I got decorated I am ordinary ``` 在上面顯示的示例中,`make_pretty()`是裝飾器。 在分配步驟中: ```py pretty = make_pretty(ordinary) ``` 裝飾了函數`ordinary()`,并將返回的函數命名為`pretty`。 我們可以看到裝飾器函數在原始函數中添加了一些新功能。 這類似于包裝禮物。 裝飾器充當包裝器。 裝飾的對象(內部實際禮物)的性質不會改變。 但是現在,它看起來很漂亮(因為它已經被裝飾了)。 通常,我們裝飾一個函數并將其重新分配為 ```py ordinary = make_pretty(ordinary). ``` 這是一個常見的構造,因此,Python 具有簡化此語法的語法。 我們可以將`@`符號與裝飾器函數的名稱一起使用,并將其放置在要裝飾的函數的定義上方。 例如, ```py @make_pretty def ordinary(): print("I am ordinary") ``` 相當于 ```py def ordinary(): print("I am ordinary") ordinary = make_pretty(ordinary) ``` 這只是實現裝飾器的語法糖。 * * * ## 帶參裝飾器 上面的裝飾器很簡單,并且只能用于沒有任何參數的函數。 如果我們的函數具有以下參數: ```py def divide(a, b): return a/b ``` 該函數具有兩個參數,`a`和`b`。 我們知道,如果我們將`b`傳遞為 0,將會產生錯誤。 ```py >>> divide(2,5) 0.4 >>> divide(2,0) Traceback (most recent call last): ... ZeroDivisionError: division by zero ``` 現在,讓我們做一個裝飾器來檢查這種情況是否會導致錯誤。 ```py def smart_divide(func): def inner(a, b): print("I am going to divide", a, "and", b) if b == 0: print("Whoops! cannot divide") return return func(a, b) return inner @smart_divide def divide(a, b): print(a/b) ``` 如果出現錯誤情況,此新實現將返回`None`。 ```py >>> divide(2,5) I am going to divide 2 and 5 0.4 >>> divide(2,0) I am going to divide 2 and 0 Whoops! cannot divide ``` 通過這種方式,我們可以修飾帶有參數的函數。 敏銳的觀察者會注意到,裝飾器內部嵌套的`inner()`函數的參數與其裝飾的函數的參數相同。 考慮到這一點,現在我們可以使通用裝飾器可以使用任意數量的參數。 在 Python 中,此魔術是通過`function(*args, **kwargs)`完成的。 這樣,`args`將是位置參數的[元組](/python-programming/tuple),`kwargs`將是關鍵字參數的[字典](/python-programming/dictionary)。 這樣的裝飾器的一個例子是: ```py def works_for_all(func): def inner(*args, **kwargs): print("I can decorate any function") return func(*args, **kwargs) return inner ``` * * * ## Python 中的鏈接裝飾器 可以在 Python 中鏈接多個裝飾器。 這就是說,一個函數可以用不同(或相同)的裝飾器多次裝飾。 我們只需將裝飾器放置在所需函數之上。 ```py def star(func): def inner(*args, **kwargs): print("*" * 30) func(*args, **kwargs) print("*" * 30) return inner def percent(func): def inner(*args, **kwargs): print("%" * 30) func(*args, **kwargs) print("%" * 30) return inner @star @percent def printer(msg): print(msg) printer("Hello") ``` **輸出**: ```py ****************************** %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Hello %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ****************************** ``` 上面的語法, ```py @star @percent def printer(msg): print(msg) ``` is equivalent to ```py def printer(msg): print(msg) printer = star(percent(printer)) ``` 鏈接裝飾器的順序很重要。 如果我們將順序顛倒為 ```py @percent @star def printer(msg): print(msg) ``` 輸出為: ```py %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ****************************** Hello ****************************** %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ```
                  <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>

                              哎呀哎呀视频在线观看