四 閉包函數、裝飾器
阿新 • • 發佈:2018-02-15
img 包含 傳參 int foo 調用 counter too urlopen
一 閉包函數
一、什麽是閉包
二、閉包的意義與應用
二 裝飾器
一、為何要用裝飾器
二、什麽是裝飾器
三、裝飾器的作用
四、裝飾器的語法
五、裝飾器補充:wraps
一 閉包函數
一、什麽是閉包
1 #內部函數包含對外部作用域而非全局作用域的引用 2 3 #提示:之前我們都是通過參數將外部的值傳給函數,閉包提供了另外一種思路 4 5 def counter(): 6 n=0 7 def incr(): 8 nonlocal n9 x=n 10 n+=1 11 return x 12 return incr 13 14 c=counter() 15 print(c()) 16 print(c()) 17 print(c()) 18 print(c.__closure__[0].cell_contents) #查看閉包的元素
二、閉包的意義與應用
1 #閉包的意義:返回的函數對象,不僅僅是一個函數對象,在該函數外還包裹了一層作用域,這使得,該函數無論在何處調用,優先使用自己外層包裹的作用域2 #應用領域:延遲計算(原來我們是傳參,現在我們是包起來) 3 from urllib.request import urlopen 4 5 def index(url): 6 def get(): 7 return urlopen(url).read() 8 return get 9 10 baidu=index(‘http://www.baidu.com‘) 11 print(baidu().decode(‘utf-8‘))
二 裝飾器(裝飾器就是閉包函數的一種應用場景)
一、為何要用裝飾器
#開放封閉原則:對修改封閉,對擴展開放
二、什麽是裝飾器
1 # 裝飾器他人的器具,本身可以是任意可調用對象,被裝飾者也可以是任意可調用對象。 2 # 強調裝飾器的原則:1 不修改被裝飾對象的源代碼 2 不修改被裝飾對象的調用方式 3 # 裝飾器的目標:在遵循1和2的前提下,為被裝飾對象添加上新功能
三、裝飾器的作用
1 import time 2 def timmer(func): 3 def wrapper(*args,**kwargs): 4 start_time=time.time() 5 res=func(*args,**kwargs) 6 stop_time=time.time() 7 print(‘run time is %s‘ %(stop_time-start_time)) 8 return res 9 return wrapper 10 11 @timmer 12 def foo(): 13 time.sleep(3) 14 print(‘from foo‘) 15 foo()無參裝飾器
1 def auth(driver=‘file‘): 2 def auth2(func): 3 def wrapper(*args,**kwargs): 4 name=input("user: ") 5 pwd=input("pwd: ") 6 7 if driver == ‘file‘: 8 if name == ‘egon‘ and pwd == ‘123‘: 9 print(‘login successful‘) 10 res=func(*args,**kwargs) 11 return res 12 elif driver == ‘ldap‘: 13 print(‘ldap‘) 14 return wrapper 15 return auth2 16 17 @auth(driver=‘file‘) 18 def foo(name): 19 print(name) 20 21 foo(‘egon‘) 22 23 有參裝飾器有參裝飾器
四、裝飾器的語法
1 # 被裝飾函數的正上方,單獨一行 2 @deco1 3 @deco2 4 @deco3 5 def foo(): 6 pass 7 8 foo=deco1(deco2(deco3(foo)))
五、裝飾器補充:wraps
1 from functools import wraps 2 3 def deco(func): 4 @wraps(func) #加在最內層函數正上方 5 def wrapper(*args,**kwargs): 6 return func(*args,**kwargs) 7 return wrapper 8 9 @deco 10 def index(): 11 ‘‘‘哈哈哈哈‘‘‘ 12 print(‘from index‘) 13 14 print(index.__doc__)
四 閉包函數、裝飾器