<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          裝飾器微妙之談

          共 1986字,需瀏覽 4分鐘

           ·

          2022-02-13 11:26


          簡單的裝飾器

          def my_decorate(fun):????def?wrapper():????????print('這是個裝飾器!')????????func()?????reture?wapper?????def greet(): print('hello world')greet = my_decorator(greet)greet()# 輸出這是個裝飾器!hello world


          這段代碼中變量 greet 指向了內(nèi)部函數(shù) wrapper(),而內(nèi)部函數(shù) wrapper() 中又會調(diào)用原函數(shù) greet(),因此,最后調(diào)用 greet() 時,就會先打印 'wrapper of decorator',然后輸出'hello world'。大家應(yīng)該都明白!


          這里的函數(shù) my_decorator() 就是一個裝飾器,它把真正需 要執(zhí)行的函數(shù) greet() 包裹在其中,并且改變了它的行為, 但是原函數(shù) greet() 不變。


          我們換一種寫法,使用Python來裝飾它

          def my_decorator(func):       def wrapper():           print('wrapper of decorator')           func()??    return wrapper@my_decoratordef?greet():????print('hello?world')greet()

          這里的@,我們稱之為語法糖,@my_decorator就相當(dāng)于 前面的greet=my_decorator(greet)語句,只不過更加 簡潔。因此,如果你的程序中有其它函數(shù)需要做類似的裝飾,你只需在它們的上方加上@decorator就可以了,這樣 就大大提高了函數(shù)的重復(fù)利用和程序的可讀性。


          帶有參數(shù)的裝飾器


          如果原函數(shù) greet() 中,有參數(shù)需要傳遞給 裝飾器怎么辦?一個簡單的辦法,是可以在對應(yīng)的裝飾器函數(shù) wrapper() 上,加上相應(yīng)的參數(shù),比如:

          def my_decorator(func): def?wrapper(message): print('wrapper of decorator') func(message) return wrapper@my_decoratordef greet(message): print(message)greet('hello world')# 輸出wrapper of decoratorhello world


          事實(shí)上,通常情況下,我們會把*args和**kwargs,作為 裝飾器內(nèi)部函數(shù) wrapper() 的參數(shù)。

          def my_decorator(func): def wrapper(*args, **kwargs): print('wrapper of decorator') func(*args, **kwargs) return wrapper

          類裝飾器

          實(shí)際上,類也可 以作為裝飾器。類裝飾器主要依賴于函數(shù)__call_(),每當(dāng)你調(diào)用一個類的示例時,函數(shù)__call__() 就會被執(zhí)行一 次。

          class Count: def __init__(self, func): self.func = func self.num_calls = 0 def __call__(self, *args, **kwargs): self.num_calls += 1 print('num of calls is: {}'.format(self.num_calls)) return self.func(*args, **kwargs)@Countdef example(): print("hello world") example()# 輸出num of calls is: 1hello world
          example()# 輸出num of calls is: 2hello world

          ?這里,定義了類 Count,初始化時傳入原函數(shù) func(), 而__call__() 函數(shù)表示讓變量 num_calls 自增 1,然后打印,并且調(diào)用原函數(shù)。因此,在我們第一次調(diào)用函數(shù) example() 時,num_calls 的值是 1,而在第二次調(diào)用時, 它的值變成了 2。



          瀏覽 50
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产午夜福利 | 国产精品天干天干 | 黄色一级电影 | 逼操逼网 | 黄片三区四区 |