<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>

          搞定三大神器之 Python 裝飾器

          共 2798字,需瀏覽 6分鐘

           ·

          2020-09-06 20:28


          我的施工之路

          1我的施工計(jì)劃

          2數(shù)字專題

          3字符串專題

          4列表專題

          5流程控制專題

          6編程風(fēng)格專題

          7函數(shù)使用

          8面向?qū)ο缶幊?上篇)

          9面向?qū)ο缶幊?下篇)

          10十大數(shù)據(jù)結(jié)構(gòu)

          11包和模塊使用總結(jié)

          12Python正則專題總結(jié)

          13設(shè)計(jì)模式

          14Python時間模塊超實(shí)用總結(jié)

          學(xué)會 Python 裝飾器

          裝飾器,幾乎各大Python框架中都能看到它的身影,足以表明它的價值!它有動態(tài)改變函數(shù)或類功能的魔力!

          本專題的目錄:

          • 學(xué)會 Python 裝飾器

            • 1 什么是裝飾器

            • 2 裝飾器的結(jié)構(gòu)

            • 3 為什么要這樣

            • 4 裝飾一個函數(shù)

            • 5 裝飾一個類

            • 6 裝飾器層疊

            • 7 溫馨提醒

            • 總結(jié)

          1 什么是裝飾器

          對于受到封裝的原函數(shù)比如f來說,裝飾器能夠在f函數(shù)執(zhí)行前或者執(zhí)行后分別運(yùn)行一些代碼。

          2 裝飾器的結(jié)構(gòu)

          裝飾器也是一個函數(shù),它裝飾原函數(shù)f或類cls后,再返回一個函數(shù)g

          裝飾一個函數(shù):

          def?decorator(f):
          ??#?定義要返回的函數(shù)
          ??def?g():
          ????print('函數(shù)f執(zhí)行前的動作')
          ????f()
          ????print('函數(shù)f執(zhí)行后的動作')
          ??return?g

          裝飾一個類:

          def?decorator(cls):
          ??#?定義要返回的函數(shù)
          ??def?g():
          ????print('類cls執(zhí)行前的動作')
          ????f()
          ????print('類cls執(zhí)行后的動作')
          ??return?g

          使用裝飾器很簡單,@+自定義裝飾器 裝飾要想裝飾的函數(shù)。

          3 為什么要這樣

          要想理解裝飾器為什么要有這種結(jié)構(gòu),要首先想明白裝飾器的目標(biāo)是什么。

          它的價值在于為原函數(shù)f增加一些行為,前提必須不能破壞函數(shù)f,所以肯定不能改變f的內(nèi)部結(jié)構(gòu),所以只能在調(diào)用f前后定義一些行為。

          同時,裝飾器函數(shù)decorator返回值又是什么?你可以思考下,返回一個函數(shù)是再好不過的了,它包裝了原函數(shù)f.

          4 裝飾一個函數(shù)

          printStar函數(shù)接收一個函數(shù)f,返回值也是一個函數(shù),所以滿足裝飾器的結(jié)構(gòu)要求,所以printStar是一個裝飾器。

          def?printStar(f):
          ????def?g():
          ????????print('*'*20)
          ????????f()
          ????????print('*'*20)
          ????return?g

          printStar裝飾器實(shí)現(xiàn)f函數(shù)執(zhí)行前、后各打印20個*字符。

          使用printStar:

          @printStar
          def?f():
          ????print('hello?world')

          調(diào)用:

          if?__name__?==?'__main__':
          ???###?改變函數(shù)功能
          ???f()

          打印結(jié)果:

          ********************
          hello?world
          ********************

          可以很方便的裝飾要想裝飾的其他函數(shù),如下:

          @printStar
          def?g():
          ????print('welcome?to?Python')

          5 裝飾一個類

          除了可以裝飾函數(shù)f外,還可以裝飾類cls,兩者原理都是一樣的。

          下面給出一個裝飾器實(shí)現(xiàn)單例模式的例子,所謂單例就是類只有唯一實(shí)例,不能有第二個。

          def?singleton(cls):
          ???instance?=?{}

          ???def?get_instance(*args,?**kwargs):
          ???????if?cls?not?in?instance:
          ???????????instance[cls]?=?cls(*args,?**kwargs)
          ???????return?instance[cls]
          ???return?get_instance

          定義字典instance,鍵值對分別為類和實(shí)例,這樣確保只cls()一次。

          使用裝飾器singleton修飾類:

          @singleton
          class?CorePoint:
          ???pass

          測試:

          if?__name__?==?'__main__':
          ???###?改變類的功能
          ???c1?=?CorePoint()
          ???c2?=?CorePoint()
          ???print(c1?is?c2)?#?True

          6 裝飾器層疊

          上面原函數(shù)f不僅能被一個裝飾器修飾,還能被n多個裝飾器修飾。

          下面再定義一個裝飾器printLine,被修飾函數(shù)執(zhí)行前后打印20個 -

          def?printLine(f):
          ????def?g():
          ????????print('-'*20)
          ????????f()
          ????????print('-'*20)
          ????return?g

          使用上文定義好的printStarprintLine同時裝飾函數(shù)f:

          @printStar
          @printLine
          def?f():
          ????print('hello?world')

          此時再調(diào)用函數(shù)f:

          if?__name__?==?'__main__':
          ???###?改變函數(shù)功能
          ???f()

          打印結(jié)果:

          ********************
          --------------------
          hello?world
          --------------------
          ********************

          f被裝飾后,先打印*,再打印 -

          層疊多一層,原函數(shù)f就變強(qiáng)大一層。使用裝飾器,還能實(shí)現(xiàn)功能抽離,進(jìn)一步實(shí)現(xiàn)松耦合。

          7 溫馨提醒

          打印原函數(shù)f的名字__name__,結(jié)果為f

          In?[1]:?def?f():?
          ???...:?????pass?

          In?[4]:?f.__name__??????????????????????????????????????????????????????????????
          Out[4]:?'f'

          但是,被裝飾后函數(shù)名字f變?yōu)間,這不是我們希望的!

          @printStar
          def?f():
          ??pass

          f()
          f.__name__?#?g

          Python提供的解決方案:使用functools模塊中的wraps裝飾器:

          from?functools?import?wraps

          def?printStar(f):
          ????@wraps(f)
          ????def?g():
          ????????print('*'*20)
          ????????f()
          ????????print('*'*20)
          ????return?g

          此時再打印被裝飾后f的名字,顯示f,正常!

          總結(jié)

          • 學(xué)會 Python 裝飾器

            • 1 什么是裝飾器

            • 2 裝飾器的結(jié)構(gòu)

            • 3 為什么要這樣

            • 4 裝飾一個函數(shù)

            • 5 裝飾一個類

            • 6 裝飾器層疊

            • 7 溫馨提醒

            • 總結(jié)

          以上就是裝飾器的核心使用邏輯專題,希望能幫助到各位讀者,若覺得有用,歡迎三連支持。咱們下個專題再見!

          推薦各位讀者關(guān)注另一個公眾號《刷題日記》,不僅僅是刷題...

          長按兩秒關(guān)注

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

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  最近好看的2019中文在线小说 | 国产在线性| 国产A片视频 | 影音先锋亚洲无码 | 国产精品日日爽夜夜爽AV |