python函數三 (裝飾器)
阿新 • • 發佈:2018-02-03
view **kwargs get 執行 特殊 對象 sleep ret 值轉換
一。函數名(學名:第一類對象)
函數名本質上就是函數的內存地址。通俗點就是特殊的普通變量
def func(): print(111) func() print(func) # 結果: # 111 # <function func at 0x00000150713F6048>
1.可以被引用(即可以賦值給其他變量)
def func(): print(‘in func‘) f = func f() # 結果: # in func
2.可以被當作容器類型的元素
def func(): print(111) def func2(): print(222) deffunc3(): print(333) li = [func(),func2(),func3()] for i in li: i # 結果: 111 222 333
3.可以當作函數的參數和返回值
def func(): print(111) func() def func2(): return func f = func2() f() # 結果: 從上到下運行,遇見func()後調用函數打印一個111, # 111 之後到f = func2(),調用func2()返回給f一個值func, # 111 最後f()即func()再次調用後打印一個111
第一類對象(first-class object)指
1.可在運行期創建
2.可用作函數參數或返回值
3.可存入變量的實體。
二。閉包
閉包的定義:內層函數,對外層函數(非全局)的變量的引用,叫做閉包
閉包的用處:如果說你內存函數是個閉包,python內部有一個機制,遇到閉包
他會在內存中開啟一個內存空間,不會隨著函數的結束而關閉
from urllib.request import urlopen print(urlopen(‘http://www.cnblogs.com/jin-xin/articles/8259929.html‘).read()) def index(url): content爬網頁(閉包用處)= urlopen(url).read() def get(): with open(‘爬蟲‘,‘a‘) as f1: f1.write(content.decode(‘utf-8‘)) return get index(‘http://www.cnblogs.com/jin-xin/articles/8259929.html‘)() index(‘http://www.cnblogs.com/jin-xin/articles/8259929.html‘)() index(‘http://www.cnblogs.com/jin-xin/articles/8259929.html‘)() index(‘http://www.cnblogs.com/jin-xin/articles/8259929.html‘)() index(‘http://www.cnblogs.com/jin-xin/articles/8259929.html‘)() def index(): url = "http://www.xiaohua100.cn/index.html" def get(): return urlopen(url).read() return get
判斷是否是閉包函數:__closure__
ef func(): name = ‘alex‘ def func2(): print(name) func2() print(func2.__closure__) #含有 cell 就是閉包 None 不是閉包 func() # 結果: # alex # (<cell at 0x0000011AD42A75B8: function object at 0x0000011AD6178A60>, <cell at 0x0000011AD42A75E8: str object at 0x0000011AD6177378>) name = ‘alex‘ def func(): def func2(): print(name) func2() print(func2.__closure__) # None 不是閉包 func() # 結果: # alex # None def func(x): def func2(): print(x) func2() print(func2.__closure__) func(‘alex‘) # 結果: # alex # (<cell at 0x0000029D98CE75B8: str object at 0x0000029D98D77538>,)
三。在外層函數內部執行內部函數
def func(): def func2(): print(111) func2() func() def func(): def func2(): print(111) return func2 func()()
四。裝飾器
比如計算一個函數的執行效率
1.最low的寫法
import time def func(): print(‘我們都一樣‘) start_time = time.time() time.sleep(0.1) func() end_time = time.time() print(‘------的執行效率%s‘%(end_time-start_time)) # 結果: # 我們都一樣 # ------的執行效率0.10034990310668945View Code
2.進階寫法
import time def func(): print(‘我們都一樣‘) def timmer(): start_time = time.time() time.sleep(0.1) func() end_time = time.time() print(‘------的執行效率%s‘%(end_time-start_time)) timmer() # 雖然也可以運行,但是影響了func()的正常運行,還可以在進階View Code
3.簡單的裝飾器
import time def func(): print(‘我們都一樣‘) def timmer(f): def inner(): start_time = time.time() time.sleep(0.1) f() end_time = time.time() print(‘------的執行效率%s‘%(end_time-start_time)) return inner func = timmer(func) func() # 可以理解為func,timmer,inner通過賦值轉換,加參數,最後只剩一個func, # 這樣就可以運行程序,又可以知道執行效率View Code
4.帶返回值的裝飾器(語法糖的用法)
@timmer 相當於 #func = timmer(func) 即待求的函數名 = 新函數名(待求的函數名)
import time def timmer(func): def inner(*args,**kwargs): start_time = time.time() time.sleep(0.1) ret = func(*args,**kwargs) end_time = time.time() print(‘------執行效率%s‘%(end_time-start_time)) return ret return inner @timmer def func(): return ‘天若有情天亦老,人間正道是滄桑‘ # func() 打印返回值的話不能寫這步,否則函數會在調用一次,多打印一次執行效率 print(func()) # 結果: # ------執行效率0.1002659797668457 # 天若有情天亦老,人間正道是滄桑
5.通用裝飾器
def wrapper(func): def inner(*args,**kwargs): ‘‘‘執行函數前的操作‘‘‘ ret = func(*args,**kwargs) ‘‘‘執行函數後的操作‘‘‘ return ret return inner @wrapper def func(): print(111) func()
python函數三 (裝飾器)