欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

python 裝飾函數(shù) 和 閉包 基礎(chǔ)總結(jié)。

系統(tǒng) 2133 0

一、 裝飾函數(shù)

(1)概念:

裝飾器本質(zhì)上是一個 Python 函數(shù)或類,它可以讓其他函數(shù)或類在不需要做任何代碼修改的前提下 增加額外功能 ,裝飾器的返回值也是一個 函數(shù)/類對象 。它經(jīng)常用于有切面需求的場景,比如:插入日志、性能測試、事務(wù)處理、緩存、權(quán)限校驗等場景,裝飾器是解決這類問題的絕佳設(shè)計。有了裝飾器,我們就可以抽離出大量與函數(shù)功能本身無關(guān)的雷同代碼到裝飾器中并繼續(xù)重用。概括的講,裝飾器的作用就是 為已經(jīng)存在的對象添加額外的功能

使用方法:

  1. 先定義一個裝飾器(帽子)
  2. 再定義你的業(yè)務(wù)函數(shù)或者類(人)
  3. 最后把這裝飾器(帽子)扣在這個函數(shù)(人)頭上

(2)實例:

  1. 日志打印器
            
              
                # 這是裝飾器函數(shù),參數(shù) func 是被裝飾的函數(shù)
              
              
                def
              
              
                logger
              
              
                (
              
              func
              
                )
              
              
                :
              
              
                def
              
              
                wrapper
              
              
                (
              
              
                *
              
              args
              
                ,
              
              
                **
              
              kw
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                '主人,我準(zhǔn)備開始執(zhí)行:{} 函數(shù)了:'
              
              
                .
              
              
                format
              
              
                (
              
              func
              
                .
              
              __name__
              
                )
              
              
                )
              
              
                # 真正執(zhí)行的是這行。
              
              
        func
              
                (
              
              
                *
              
              args
              
                ,
              
              
                **
              
              kw
              
                )
              
              
                print
              
              
                (
              
              
                '主人,我執(zhí)行完啦。'
              
              
                )
              
              
                return
              
               wrapper
@logger  
              
                # =》 add = logger(add)
              
              
                def
              
              
                add
              
              
                (
              
              x
              
                ,
              
               y
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                '{} + {} = {}'
              
              
                .
              
              
                format
              
              
                (
              
              x
              
                ,
              
               y
              
                ,
              
               x
              
                +
              
              y
              
                )
              
              
                )
              
            
          

執(zhí)行:
在這里插入圖片描述
2. 時間計時器

            
              
                # 這是裝飾函數(shù)
              
              
                def
              
              
                timer
              
              
                (
              
              func
              
                )
              
              
                :
              
              
                def
              
              
                wrapper
              
              
                (
              
              
                *
              
              args
              
                ,
              
              
                **
              
              kw
              
                )
              
              
                :
              
              
        t1
              
                =
              
              time
              
                .
              
              time
              
                (
              
              
                )
              
              
                # 這是函數(shù)真正執(zhí)行的地方
              
              
        func
              
                (
              
              
                *
              
              args
              
                ,
              
              
                **
              
              kw
              
                )
              
              
        t2
              
                =
              
              time
              
                .
              
              time
              
                (
              
              
                )
              
              
                # 計算下時長
              
              
        cost_time 
              
                =
              
               t2
              
                -
              
              t1 
        
              
                print
              
              
                (
              
              
                "花費時間:{}秒"
              
              
                .
              
              
                format
              
              
                (
              
              cost_time
              
                )
              
              
                )
              
              
                return
              
               wrapper

              
                import
              
               time

@timer

              
                def
              
              
                want_sleep
              
              
                (
              
              sleep_time
              
                )
              
              
                :
              
              
    time
              
                .
              
              sleep
              
                (
              
              sleep_time
              
                )
              
              

want_sleep
              
                (
              
              
                10
              
              
                )
              
              
                #花費時間:10.000298261642456秒
              
            
          
  1. 帶參數(shù)的函數(shù)裝飾器
            
              
                def
              
              
                say_hello
              
              
                (
              
              contry
              
                )
              
              
                :
              
              
                def
              
              
                wrapper
              
              
                (
              
              func
              
                )
              
              
                :
              
              
                def
              
              
                deco
              
              
                (
              
              
                *
              
              args
              
                ,
              
              
                **
              
              kwargs
              
                )
              
              
                :
              
              
                if
              
               contry 
              
                ==
              
              
                "china"
              
              
                :
              
              
                print
              
              
                (
              
              
                "你好!"
              
              
                )
              
              
                elif
              
               contry 
              
                ==
              
              
                "america"
              
              
                :
              
              
                print
              
              
                (
              
              
                'hello.'
              
              
                )
              
              
                else
              
              
                :
              
              
                return
              
              
                # 真正執(zhí)行函數(shù)的地方
              
              
            func
              
                (
              
              
                *
              
              args
              
                ,
              
              
                **
              
              kwargs
              
                )
              
              
                return
              
               deco
    
              
                return
              
               wrapper


              
                # 小明,中國人
              
              
@say_hello
              
                (
              
              
                "china"
              
              
                )
              
              
                def
              
              
                xiaoming
              
              
                (
              
              
                )
              
              
                :
              
              
                pass
              
              
                # jack,美國人
              
              
@say_hello
              
                (
              
              
                "america"
              
              
                )
              
              
                def
              
              
                jack
              
              
                (
              
              
                )
              
              
                :
              
              
                pass
              
            
          

python 裝飾函數(shù) 和 閉包 基礎(chǔ)總結(jié)。_第1張圖片
4. 不帶參數(shù)的類裝飾器
基于類裝飾器的實現(xiàn),必須實現(xiàn) call 和 __init__兩個內(nèi)置函數(shù)。
init :接收被裝飾函數(shù)
call :實現(xiàn)裝飾邏輯。

            
              
                class
              
              
                logger
              
              
                (
              
              
                object
              
              
                )
              
              
                :
              
              
                def
              
              
                __init__
              
              
                (
              
              self
              
                ,
              
               func
              
                )
              
              
                :
              
              
        self
              
                .
              
              func 
              
                =
              
               func

    
              
                def
              
              
                __call__
              
              
                (
              
              self
              
                ,
              
              
                *
              
              args
              
                ,
              
              
                **
              
              kwargs
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                "[INFO]: the function {func}() is running..."
              
              \
            
              
                .
              
              
                format
              
              
                (
              
              func
              
                =
              
              self
              
                .
              
              func
              
                .
              
              __name__
              
                )
              
              
                )
              
              
                return
              
               self
              
                .
              
              func
              
                (
              
              
                *
              
              args
              
                ,
              
              
                **
              
              kwargs
              
                )
              
              

@logger

              
                def
              
              
                say
              
              
                (
              
              something
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                "say {}!"
              
              
                .
              
              
                format
              
              
                (
              
              something
              
                )
              
              
                )
              
              

say
              
                (
              
              
                "hello"
              
              
                )
              
              
                #[INFO]: the function say() is running...
              
              
                #say hello!
              
            
          
  1. 帶參數(shù)的類裝飾器
    上面不帶參數(shù)的例子,你發(fā)現(xiàn)沒有,只能打印INFO級別的日志,正常情況下,我們還需要打印DEBUG WARNING等級別的日志。這就需要給類裝飾器傳入?yún)?shù),給這個函數(shù)指定級別了。

帶參數(shù)和不帶參數(shù)的類裝飾器有很大的不同。

init :不再接收被裝飾函數(shù),而是接收傳入?yún)?shù)。
call :接收被裝飾函數(shù),實現(xiàn)裝飾邏輯。

            
              
                class
              
              
                logger
              
              
                (
              
              
                object
              
              
                )
              
              
                :
              
              
                def
              
              
                __init__
              
              
                (
              
              self
              
                ,
              
               level
              
                =
              
              
                'INFO'
              
              
                )
              
              
                :
              
              
        self
              
                .
              
              level 
              
                =
              
               level

    
              
                def
              
              
                __call__
              
              
                (
              
              self
              
                ,
              
               func
              
                )
              
              
                :
              
              
                # 接受函數(shù)
              
              
                def
              
              
                wrapper
              
              
                (
              
              
                *
              
              args
              
                ,
              
              
                **
              
              kwargs
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                "[{level}]: the function {func}() is running..."
              
              \
                
              
                .
              
              
                format
              
              
                (
              
              level
              
                =
              
              self
              
                .
              
              level
              
                ,
              
               func
              
                =
              
              func
              
                .
              
              __name__
              
                )
              
              
                )
              
              
            func
              
                (
              
              
                *
              
              args
              
                ,
              
              
                **
              
              kwargs
              
                )
              
              
                return
              
               wrapper  
              
                #返回函數(shù)
              
              

@logger
              
                (
              
              level
              
                =
              
              
                'WARNING'
              
              
                )
              
              
                def
              
              
                say
              
              
                (
              
              something
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                "say {}!"
              
              
                .
              
              
                format
              
              
                (
              
              something
              
                )
              
              
                )
              
              

say
              
                (
              
              
                "hello"
              
              
                )
              
              
                #[WARNING]: the function say() is running...
              
              
                #say hello!
              
            
          
  1. 內(nèi)置裝飾器:property
            
            
          
  1. 如果 decorator本身需要傳入?yún)?shù) ,那就需要編寫一個返回decorator的高階函數(shù)。(即再嵌套一個decorator函數(shù)):
            
              
                def
              
              
                log
              
              
                (
              
              text
              
                )
              
              
                :
              
              
                def
              
              
                decorator
              
              
                (
              
              func
              
                )
              
              
                :
              
              
        @functools
              
                .
              
              wraps
              
                (
              
              func
              
                )
              
              
                #把原始函數(shù)的__name__等屬性復(fù)制到wrapper()函數(shù)中
              
              
                def
              
              
                wrapper
              
              
                (
              
              
                *
              
              args
              
                ,
              
              
                **
              
              kw
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                '%s %s():'
              
              
                %
              
              
                (
              
              text
              
                ,
              
               func
              
                .
              
              __name__
              
                )
              
              
                )
              
              
                return
              
               func
              
                (
              
              
                *
              
              args
              
                ,
              
              
                **
              
              kw
              
                )
              
              
                return
              
               wrapper
    
              
                return
              
               decorator

@log
              
                (
              
              
                'execute'
              
              
                )
              
              
                #now = log('execute')(now)
              
              
                def
              
              
                now
              
              
                (
              
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                '2015-3-25'
              
              
                )
              
              

now
              
                (
              
              
                )
              
              
                #execute now():
              
              
                #2015-3-25
              
            
          

首先執(zhí)行l(wèi)og(‘execute’),返回的是decorator函數(shù),再調(diào)用返回的函數(shù),參數(shù)是now函數(shù),返回值最終是wrapper函數(shù)。

二、閉包

(1)概念:

在一個內(nèi)部函數(shù)中,對外部作用域的變量進行引用,(并且一般外部函數(shù)的返回值為內(nèi)部函數(shù)),那么內(nèi)部函數(shù)就被認為是閉包。
維基百科上的解釋是:

              
                在計算機科學(xué)中,閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,
是引用了自由變量的函數(shù)。這個被引用的自由變量將和這個函數(shù)一同存在,
即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。
所以,有另一種說法認為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實體。

              
            

在這里插入圖片描述

add訪問了外部函數(shù)start的變量,并且函數(shù)返回值為add函數(shù)(python可以 返回函數(shù)
python 裝飾函數(shù) 和 閉包 基礎(chǔ)總結(jié)。_第2張圖片
閉包,顧名思義,就是一個封閉的包裹,里面包裹著 自由變量 ,就像在類里面定義的屬性值一樣,自由變量的可見范圍隨同包裹,哪里可以訪問到這個包裹,哪里就可以訪問到這個自由變量。

再通過Python的語言介紹一下,一個閉包就是你調(diào)用了一個函數(shù)A,這個函數(shù)A返回了一個函數(shù)B給你。這個返回的函數(shù)B就叫做閉包。你在調(diào)用函數(shù)A的時候傳遞的參數(shù)就是自由變量(當(dāng)函數(shù)A的生命周期結(jié)束之后,自由變量依然存在,因為它被閉包引用了,所以不會被回收。)。

(2)常見問題

  1. 閉包無法修改 外部函數(shù) 局部變量 (即add函數(shù)無法修改start函數(shù)定義的變量)

  2. 閉包使得 局部變量 函數(shù)外 被訪問成為可能

  3. 閉包避免了使用全局變量

  4. 閉包允許將函數(shù)與其所操作的某些數(shù)據(jù)(環(huán)境)關(guān)連起來。

  5. 裝飾器就是一種的閉包的應(yīng)用,只不過其傳遞的是 函數(shù)

  6. 閉包的最大特點是可以將 父函數(shù)的變量與內(nèi)部函數(shù)綁定 ,并返回綁定變量后的函數(shù)(也即閉包)。(類似類)

  7. python循環(huán)中不包含域的概念。

python 裝飾函數(shù) 和 閉包 基礎(chǔ)總結(jié)。_第3張圖片
loop在python中是沒有域的概念的,flist在向列表中添加func的時候,并沒有保存i的值,而是當(dāng)執(zhí)行f(2)的時候才去取,這時候循環(huán)已經(jīng)結(jié)束,i的值是2,所以結(jié)果都是4。

解決辦法:
在func外面再定義一個makefun函數(shù),func形成閉包。 python 裝飾函數(shù) 和 閉包 基礎(chǔ)總結(jié)。_第4張圖片
參考:
https://foofish.net/python-closure.html
https://zhuanlan.zhihu.com/p/22229197


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久草6 | 超级碰碰碰视频在线观看 | 好吊在线 | 午夜视频在线观看一区 | 在线观看国产视频 | 狠狠久久| 欧美成人私人视频88在线观看 | 偷拍自拍色 | 欧美黑人ⅹxxx片 | 亚洲精品视频一区 | 久久人 | 久久高清 | 天天干夜夜噜 | 苏晓晖个人简介军衔 | 婷婷色综合久久五月亚洲 | 日韩毛片网站 | 奇米影视 首页 | 久久精品久久久久久 | 国产成人综合日韩精品婷婷九月 | 国产片欧美片亚洲片久久综合 | 亚洲精品一区二区三区四区高清 | 欧美系列在线播放 | 狠狠狠狠狠狠狠狠狠狠 | 亚洲国产欧洲精品路线久久 | 国产综合一区二区 | 99精品99 | 777色狠狠一区二区三区香蕉 | 最新欧美精品一区二区三区 | 亚洲w码 | 日韩欧美一区二区视频 | 欧美一区久久 | 黄色精品视频 | 国产精品视频99 | 九九视频在线看精品 | 一国产一级淫片a免费播放口 | 中文字幕电影在线观看 | 两性午夜视频 | 国产福利合集 | 国产亚洲精品精品国产亚洲综合 | 免费看一级欧美毛片视频 | 色综合区 |