1.1什麼是閉包?閉包
#內部函數包含對外部做用域而非全局做用域的引用 #提示:以前咱們都是經過參數將外部的值傳給函數,閉包提供了另一種思路,包起來嘍,包起呦,包起來哇 def counter(): n=0 def incr(): nonlocal n x=n n+=1 return x return incr c=counter() print(c()) print(c()) print(c()) print(c.__closure__[0].cell_contents) #查看閉包的元素
1.2 閉包的意義與應用app
#閉包的意義:返回的函數對象,不單單是一個函數對象,在該函數外還包裹了一層做用域,這使得,該函數不管在何處調用,優先使用本身外層包裹的做用域 #應用領域:延遲計算(原來咱們是傳參,如今咱們是包起來) from urllib.request import urlopen def index(url): def get(): return urlopen(url).read() return get baidu=index('http://www.baidu.com') print(baidu().decode('utf-8'))
裝飾器就是閉包函數的一種應用場景函數
開放封閉原則:對修改封閉,對擴展開
裝飾器他人的器具,自己能夠是任意可調用對象,被裝飾者也能夠是任意可調用對象。 強調裝飾器的原則:1 不修改被裝飾對象的源代碼 2 不修改被裝飾對象的調用方式 裝飾器的目標:在遵循1和2的前提下,爲被裝飾對象添加上新功能
import time def timmer(func): def wrapper(*args,**kwargs): start_time=time.time() res=func(*args,**kwargs) stop_time=time.time() print('run time is %s' %(stop_time-start_time)) return res return wrapper @timmer def foo(): time.sleep(3) print('from foo') foo()
有參裝飾器 def auth(driver='file'): def auth2(func): def wrapper(*args,**kwargs): name=input("user: ") pwd=input("pwd: ") if driver == 'file': if name == 'egon' and pwd == '123': print('login successful') res=func(*args,**kwargs) return res elif driver == 'ldap': print('ldap') return wrapper return auth2 @auth(driver='file') def foo(name): print(name) foo('egon')
被裝飾函數的正上方,單獨一行 @deco1 @deco2 @deco3 def foo(): pass foo=deco1(deco2(deco3(foo)))
from functools import wraps def deco(func): @wraps(func) #加在最內層函數正上方 def wrapper(*args,**kwargs): return func(*args,**kwargs) return wrapper @deco def index(): '''哈哈哈哈''' print('from index') print(index.__doc__)