2018-09-05 python里的閉包函數(shù)和裝飾器以及高階裝飾器

在學(xué)習(xí)python中荆责,剛開始沒重視閉包函數(shù)和裝飾器滥比,后來發(fā)現(xiàn)裝飾器非常重要,在這重新梳理一下做院,也讓自己再加深下印象盲泛。

一、函數(shù)閉包:? ?

什么是閉包函數(shù)键耕,其實就是必須滿足以下三點的函數(shù):

?1寺滚,必須要有一個內(nèi)嵌函數(shù)? ??

2,嵌套函數(shù)必須引用封閉函數(shù)中的變量? ?

?3屈雄,閉包函數(shù)必須要返回內(nèi)嵌函數(shù)

比如求一個y = kx +b;這種求一次函數(shù)直線上任意一個x值的y值村视;

傳統(tǒng)函數(shù)定義可能如下:

def line(k,x,b):

????????return k*x+b

res = line(1,2,3)

print(res)

# 5

這種函數(shù)當(dāng)然可是實現(xiàn),但是就是輸入形參太多酒奶,而且蚁孔,加入一條直線固定,只需要輸入一個x即可:所以可是重新定義一個閉包函數(shù)惋嚎,如下:

def lineOut(k,b):

????????def line(x):

????????????????return k*x+b

????????return line

line = lineOut(1,2)

res = line(3)

print(res)

# 5

這樣的話杠氢,就可以只調(diào)用line這個函數(shù)返回函數(shù),進(jìn)行直傳一個參數(shù)就可以了另伍。

二鼻百、閉包函數(shù)的用途:? ?

?1,裝飾器:其中一個應(yīng)用寫了一個登錄功能摆尝,需要統(tǒng)計這個功能執(zhí)行花費的時間温艇,可以使用裝飾器實現(xiàn);還有可以實現(xiàn)打印日志? ?

?2,實現(xiàn)面向?qū)ο蠖楣热鏙avaScript中使用閉包函數(shù)實現(xiàn)面向?qū)ο蟮墓δ苌装瑢傩赞k法? ??

3,實現(xiàn)單利模式臼朗,單利類邻寿,一個類只有一個實例蝎土。'''

下面有這個實例是定義一個求和函數(shù)视哑,然后用閉包函數(shù)調(diào)用绣否,并判斷條件是否滿足是整型,滿足條件就執(zhí)行求和函數(shù)挡毅,本身求和函數(shù)代碼不做任何修改蒜撮,更加模塊化,更方便維護和調(diào)用跪呈,耦合性降低不少段磨,具體代碼如下:

def mySum(*args):

????????return sum(args)

def dec(fun):

????????def inDec(*args):

????????????????if len(args) ==0:

????????????????????????return 0

? ? ? ? ????????for i in args:

????????????????????????if not isinstance(i,int):

????????????????????????????????return 0

? ? ? ? ? ? ? ? ?return fun(*args)

????????return inDec

res = dec(mySum)

# res1 = res(1,2,3,89)

# res1 = res("99",9)

res1 = res()

print(res1)

三、裝飾器:

其實上面那個求和函數(shù)已經(jīng)用到了裝飾器的作用耗绿,就是執(zhí)行指定函數(shù)時還能執(zhí)行其他操作苹支,并不影響原函數(shù)的代碼,裝飾器本質(zhì)就是一個函數(shù)误阻,但是它有特殊作用债蜜,它用來裝飾別的函數(shù),給其他函數(shù)附加新的功能

? ? 特點究反,原則:? ? ? ?

?1寻定,不能修改被裝飾的函數(shù)的源代碼? ? ? ??

2,不能改變裝飾器函數(shù)的調(diào)用方式'''

裝飾器和閉包函數(shù)最大的區(qū)別是在于它的引用方式精耐,使用"@"寫在裝飾器函數(shù)之前狼速,并整體放在需要裝飾的函數(shù)前面一行,這樣在調(diào)用功能函數(shù)時卦停,系統(tǒng)就會自動執(zhí)行裝飾器函數(shù)向胡,并且執(zhí)行返回的嵌套函數(shù),說白了就是省略了之前自己手動調(diào)用返回嵌套函數(shù)的步驟惊完,并且在嵌套函數(shù)內(nèi)部僵芹,調(diào)用了功能函數(shù)。其中有幾點需要強調(diào):

1专执,裝飾器函數(shù)必須要有形參淮捆,且傳入的是函數(shù)名;

2本股,嵌套函數(shù)會自動執(zhí)行攀痊,且會自動把功能的實參復(fù)制一份到自己的實參列表,并且在執(zhí)行其他功能外拄显,會調(diào)用功能函數(shù)苟径;

3,裝飾器給人感覺是先執(zhí)行裝飾器函數(shù)功能躬审,后執(zhí)行功能函數(shù)棘街,其實不然蟆盐,它是在裝飾器內(nèi)部及已經(jīng)調(diào)用功能函數(shù),所以調(diào)用功能函數(shù)時遭殉,其實是值執(zhí)行裝飾器函數(shù)石挂,只不過是執(zhí)行中會調(diào)用功能函數(shù);(不知道大家有沒有看懂险污。痹愚。。蛔糯。拯腮。∫响看下面代碼动壤,自己運行,就能理解)

4淮逻,最后注意裝飾器函數(shù)的返回值設(shè)計

實例一:測試函數(shù)執(zhí)行順序

def log(func):

????????def wrapper(*args,**kwargs):

????????????????print("begin call %s"%func.__name__)

????????????????tem = func(*args,**kwargs)

????????????????print("after call %s"%func.__name__)

????????????????return tem

????????return wrapper

?@log

def new():

????????print("正在執(zhí)行琼懊。。弦蹂。肩碟。")

new = new()

print(new)

實例二:#定義一個裝飾器,用來測試一個函數(shù)的執(zhí)行時間

import os

import time

#定義一個裝飾器凸椿,用來測試一個函數(shù)的執(zhí)行時間

def getTime(func):

????????def wrapper(*args,**kwargs):

????????????????startTime = time.time()

????????????????func(*args, **kwargs)

????????????????endTime = time.time()

????????????????print("%s執(zhí)行了%s秒"%(func.__name__,endTime-startTime))

????????return wrapper

@getTime

def f1():

????????print("正在執(zhí)行削祈。。脑漫。髓抑。。优幸。吨拍。")

????????time.sleep(1)

f1()

實例三:高階裝飾器,其實就是閉包函數(shù)里面還是一個閉包函數(shù)网杆,就是高階裝飾器:

def outLog(text):

????????def log(func):

????????????????def wrapper(*args,**kwargs):

????????????????????????print(text)

? ? ? ? ? ? ? ? ? ? ? ? print("%s執(zhí)行了"%func.__name__)

????????????????????????res = func(*args,**kwargs)

????????????????????????return res

? ? ? ? ? ? ? ?return wrapper

? ? ? ? ?return log

@outLog("這是打印的text")

def f3(x,y):

????????return x+y

res = f3(1,898)

print(res)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末羹饰,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子碳却,更是在濱河造成了極大的恐慌队秩,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昼浦,死亡現(xiàn)場離奇詭異馍资,居然都是意外死亡,警方通過查閱死者的電腦和手機关噪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門鸟蟹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乌妙,“玉大人,你說我怎么就攤上這事建钥√僭希” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵锦针,是天一觀的道長荠察。 經(jīng)常有香客問我置蜀,道長奈搜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任盯荤,我火速辦了婚禮馋吗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘秋秤。我一直安慰自己各吨,他們只是感情好姑廉,可當(dāng)我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般堡纬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上均函,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天升熊,我揣著相機與錄音,去河邊找鬼涩咖。 笑死海诲,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的檩互。 我是一名探鬼主播特幔,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼闸昨!你這毒婦竟也來了蚯斯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤饵较,失蹤者是張志新(化名)和其女友劉穎拍嵌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體告抄,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡撰茎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了打洼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片龄糊。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡逆粹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出炫惩,到底是詐尸還是另有隱情僻弹,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布他嚷,位于F島的核電站蹋绽,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏筋蓖。R本人自食惡果不足惜卸耘,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望粘咖。 院中可真熱鬧蚣抗,春花似錦、人聲如沸瓮下。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讽坏。三九已至锭魔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間路呜,已是汗流浹背迷捧。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拣宰,地道東北人党涕。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像巡社,于是被迫代替她去往敵國和親膛堤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容