閉包與裝飾器
阿新 • • 發佈:2018-02-04
函數名 for循環 a + b 使用 style 裝飾 post 內存地址 lee
一、函數名
函數名在本質上就是函數的內存地址,函數名有以下功能:
函數名可以賦值給別的變量;;
函數名還可以當做容器類型裏面的元素,(列表、字典);
函數名可以當做函數的參數和返回值;具體實例如下:
#!/usr/bin/python # -*- encodeing:utf-8 -*- # 函數可以賦值給別的變量 # def func(): # print(‘caoyf‘) # a = func # 此函數名賦值給了變量‘a‘,在下面直接輸入a()就相當於調用func函數 # a() #函數名可以當做容器類型的元素:例如:列表 # def func(): #函數名print(‘我是func函數‘) # def inner(): # print(‘我是inner函數‘) # def caoyf(): # print(‘我是曹艷飛函數‘) # a = [func,inner,caoyf] # 列表的查詢方式可以通過切邊進行查看,為了方便查看所有結果,使用for循環一次查看所有的結果 # for i in a: # i() # 函數名可以當做函數的參數和返回值使用: # def func(): # print(‘func函數‘) # def inner(name): # name() # return name# a = inner(func) # print(a)
二、閉包
函數的閉包定義:
在函數內部再定義一個函數,並且這個函數用到了外邊函數的變量,那麽將這個函數以及用到的一些變量稱之為閉包,實例如下:
#!/usr/bin/python # -*- encodeing:utf-8 -*- # 內部函數調用外部函數的變量 # def func(a): # def inner(b): # return a + b # 在inner函數裏面調用了func函數的變量a,然後將inner返回給調用者 # return inner # ret = func(30)(20)內部函數調用外部函數的變量# print(ret)
內部函數對外部函數作用域變量的引用(非全局變量),則成為內部函數為閉包,實例如下:
判斷一個函數是不是閉包,可以使用__closure__方法測試,如果打印出來的是cell那這就是一個閉包,如果打印的是None,那就不是閉包,實例如下:
#!/usr/bin/python # -*- encodeing:utf-8 -*- # def func(): # name = ‘caoyf‘ # def inner(): # print(name) # return inner # ret = func() # inner函數裏面調用了func函數的變量name。 # ret() # 判斷是不是閉包 # def func(): # name = ‘caoyf‘ # def inner(): # print(name) # print(inner.__closure__) #這個函數是一個閉包,因為inner函數裏面調用了func函數的變量name。 # return inner # ret = func() # ret() # def func(): # name = ‘caoyf‘ # def inner(): # print(666666) # print(inner.__closure__) # inner() #這個函數就不是閉包,因為內部沒有引用外部的變量 # ret = func()閉包與判斷是不是閉包
三、裝飾器
現在有這麽一個開發需求,領導想知道每段代碼的耗時時間,來評比工作的考核
一般開發的代碼內容如下:
#!/usr/bin/python # -*- encodeing:utf-8 -*- def func(): print(‘執行此段代碼,你會看到意想不到的結果‘)
靈機一動,寫了下面的代碼:
#!/usr/bin/python # -*- encodeing:utf-8 -*- import time def func(): start = time.time() time.sleep(0.1) # 假設為執行時間,實際代碼肯定不是一個print能搞定的 print("執行此段代碼,你會看到意想不到的結果") end = time.time() print(‘func函數共用時%s‘ %(end - start)) func()View Code
在接下來的幾天時間裏,開發的同事看見我都想打死我,我有趕緊的把原來的代碼拿出來進行修改,於是又出來了下面的版本,同時告訴大家以後再使用的時候直接調用timeer函數就行了;
#!/usr/bin/python # -*- encodeing:utf-8 -*- # import time # def func(): # print(‘執行此段代碼,你會看到意想不到的結果‘) # def timeer(func): # start = time.time() # func() # end = time.time() # print(‘func函數共用時%s‘ %(start - end)) # f1 = func # func = timeer # func(f1)time函數
後來有人告訴我裏面的代碼還可以節儉,可以使用語法糖的方式,這樣同事在計算時間的函數前加一句@timeer就可以了,於是又出了一個版本;
#!/usr/bin/python # -*- encodeing:utf-8 -*- import time def timeer(f): def inner(): start = time.time() f() end = time.time() print(‘func函數共用時%s‘ %(start - end)) return inner @timeer def func(): print(‘執行此段代碼,你會看到意想不到的結果‘) func()@語法糖
為了方便後期開發同事的使用,有修改了一次版本,增加了帶有參數的和返回值的,以下是萬能版本的timeer函數裝飾器:
#!/usr/bin/python # -*- encodeing:utf-8 -*- import time def timeer(f): def inner(*args,**kwargs): start = time.time() ret = f(*args,**kwargs) end = time.time() print(‘func函數共用時%s‘ %(start - end)) return ret return inner @timeer def func(*args): print(‘執行此段代碼,你會看到意想不到的結果 %s‘%args) func(‘www.xxxooo.com‘)萬能裝飾器
閉包與裝飾器