1. 程式人生 > >四 閉包函數、裝飾器

四 閉包函數、裝飾器

img 包含 傳參 int foo 調用 counter too urlopen

一 閉包函數

  一、什麽是閉包

  二、閉包的意義與應用

二 裝飾器

  一、為何要用裝飾器

  二、什麽是裝飾器

  三、裝飾器的作用

  四、裝飾器的語法

  五、裝飾器補充:wraps

一 閉包函數

一、什麽是閉包

 1 #內部函數包含對外部作用域而非全局作用域的引用
 2 
 3 #提示:之前我們都是通過參數將外部的值傳給函數,閉包提供了另外一種思路
 4 
 5         def counter():
 6             n=0
 7             def incr():
 8                 nonlocal n
9 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__)

四 閉包函數、裝飾器