定義
本質就是函數,功能 爲其它函數添加附加功能python
原則:閉包
- 不修改被修飾函數的源代碼
- 不修改被修飾函數的調用方式
裝飾器的知識儲備
框架
裝飾器 = 高階函數+函數嵌套+閉包 分佈式
這裏面要明確高階函數的定義
ide
1 import time#導入時間模塊兒 2 def foo(func): # func = test 3 def bar(*args,**kwargs): 4 start_time = time.time() 5 res=func(*args,**kwargs) # 這裏就是在運行test() 賦予變量 6 stop_time = time.time() 7 print("狼來了的時間爲%s" %(stop_time-start_time)) 8 return res # 返回test()的值 9 return bar 10 @foo # @foo 至關於 test=foo(test) 調用foo函數並將test傳給func 11 def test(name,age): 12 time.sleep(1) 13 print("名字叫%s年齡爲%s的狼來了" %(name,age)) 14 return "村裏的羊被吃了" 15 ret = test("灰太狼",age=10) # test()意在運行bar() # 輸出res的返回值 16 print(ret)
分佈式講解:函數
高階函數的定義
一、函數接收的參數是一個函數名 二、函數的返回值是一個函數名post
以上條件任意知足一條,均可以稱之爲高階函數spa
1 def foo(): 2 print('個人函數名字做爲參數傳給高階函數啦') 3 def gao_jie1(func): # 傳函數名 func = foo 4 print('我就是高階函數1號,我接收的參數名是%s' %func) 5 func() # 意在運行 foo()函數 6 7 def gao_jie2(func): # func = foo 8 print('我就是高階函數2號,個人返回值是%s' %func) 9 return func # 此時func爲返回foo的的內存地址 10 11 gao_jie1(foo) 12 print(gao_jie2(foo)) 13 14 輸出 15 我就是高階函數1號,我接收的參數名是<function foo at 0x000001FDF179F598> 16 個人函數名字做爲參數傳給高階函數啦 17 我就是高階函數2號,個人返回值是<function foo at 0x000001FDF179F598> 18 <function foo at 0x000001FDF179F598>
1 import time 2 def foo(): 3 time.sleep(2) 4 print("狼來了") 5 def test(func): # func = foo 6 start_time = time.time() 7 func() # func()意在調用 foo()函數 8 stop_time = time.time() 9 print("狼來的時間爲%s" %(stop_time-start_time)) 10 test(foo) # 調用test()函數 並用函數名爲參數傳進去
總結:一、函數接收的參數是一個函數名
code
做用:在不修改函數源代碼的前提下添加新功能blog
不足:改變了函數的調用方式
#高階函數應用2:把函數名當作參數傳給高階函數,高階函數直接返回函數名 import time def foo(): time.sleep(2) print("狼來了") def test(func): # func = foo的內存地址 start_time = time.time() return func # 返回值爲foo的內存地址 stop_time = time.time() print("狼來的時間爲%s" %(stop_time-start_time)) foo = test(foo) # 調用test函數並將函數名foo作爲參數傳進去 print(foo) # 輸出返回值的結果 foo的內存地址 foo() # 運行foo()函數 #沒有改變函數foo的調用方式,可是也沒有給函數增長新功能
總結:二、函數的返回值是一個函數名
做用:不修改函數的調用方式
不足:沒有爲函數增長新的功能
函數嵌套
1 def father(name): 2 print('from father %s' %name) 3 def son(): 4 print('from son') 5 def grandson(): 6 print('from grandson') 7 grandson() 8 son() 9 father('舒克') 10 11 輸出 12 from father 舒克 13 from son 14 from grandson
閉包
1 ''' 2 閉包:在一個做用域裏放入定義變量,至關於打了一個包 3 ''' 4 def father(name): 5 def son(): 6 # name='alex' 7 print('我爸爸是 [%s]' %name) 8 def grandson(): 9 # name='wupeiqi' 10 print('我爺爺是 [%s]' %name) 11 grandson() 12 son() 13 father('舒克')
無參裝飾器=高階函數+嵌套函數
基本框架
1
2
3
4
5
|
# 無參裝飾器,這是一個實現裝飾器最基本的框架
def
timmer(func):
def
bar():
func()
return
bar
|
加入參數以後
1
2
3
4
5
|
# 帶參數裝飾器
def
timmer(func):
def
bar(
*
args,
*
*
kwargs):
func(
*
args,
*
*
kwargs)
return
bar
|
加入時間功能
1
2
3
4
5
6
7
8
9
|
# 加一個時間的小功能
import
time
def
timmer(func):
def
bar(
*
args,
*
*
kwargs):
start_time
=
time.time()
func(
*
args,
*
*
kwargs)
stop_time
=
time.time()
print
(
"狼來的時間爲%s"
%
(stop_time
-
start_time))
return
bar
|
加入函數運行的返回值
1
2
3
4
5
6
7
8
9
10
|
# 加入函數返回值
import
time
def
timmer(func):
def
bar(
*
args,
*
*
kwargs):
start_time
=
time.time()
res
=
func(
*
args,
*
*
kwargs)
stop_time
=
time.time()
print
(
"狼來的時間爲%s"
%
(stop_time
-
start_time))
return
res
return
bar
|
使用裝飾器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import
time
def
timmer(func):
def
bar(
*
args,
*
*
kwargs):
start_time
=
time.time()
res
=
func(
*
args,
*
*
kwargs)
stop_time
=
time.time()
print
(
"博爾特跑10米的時間爲%s"
%
(stop_time
-
start_time))
return
res
return
bar
# 使用裝飾器
def
test():
time.sleep(
1
)
print
(
"到達終點"
)
return
"世界飛人"
test
=
timmer(test)
print
(test())
輸出
到達終點
博爾特跑
10
米的時間爲
1.0006155967712402
世界飛人
|
語法糖@
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import
time
def
timmer(func):
def
bar(
*
args,
*
*
kwargs):
start_time
=
time.time()
res
=
func(
*
args,
*
*
kwargs)
stop_time
=
time.time()
print
(
"博爾特跑10米的時間爲%s"
%
(stop_time
-
start_time))
return
res
return
bar
# 使用裝飾器
@timmer
# @timmer就至關於 test=timmer(test)
def
test():
time.sleep(
1
)
print
(
"到達終點"
)
return
"世界飛人"
# test=timmer(test)
print
(test())
# test()是在運行bar()函數
|
應用示例
user_list=[ {'name':'alex','passwd':'123'}, {'name':'linhaifeng','passwd':'123'}, {'name':'wupeiqi','passwd':'123'}, {'name':'yuanhao','passwd':'123'}, {'name':'病毒尖er','passwd':'123'}, ] current_user={'username':None,'login':False} def auth_func(func): # 用戶登錄驗證 def bar(*args,**kwargs): if current_user["username"] and current_user["login"]: res = func(*args,**kwargs) return res for i in range(3): username = input("請輸入用戶名:").strip() passwd = input("請輸入密碼:").strip() for item in user_list: if username == item["name"] and passwd == item["passwd"]: current_user["username"] = username current_user["login"] = True res=func(*args,**kwargs) return res else: print("您輸入的用戶名或者密碼有誤") return bar @auth_func # 至關於index=auth_func(index) def index(): print("歡迎來到京東商城" ) @auth_func # 至關於home=auth_func(home) def home(name): print("%s歡迎回家" %name) @auth_func # 至關於shop_car=auth_func() def shop_car(name): print("%s的購物車是空的,趕忙購物咯" %name) index() home(current_user["username"]) shop_car(current_user["username"])
1 user_list=[ 2 {'name':'alex','passwd':'123'}, 3 {'name':'linhaifeng','passwd':'123'}, 4 {'name':'wupeiqi','passwd':'123'}, 5 {'name':'yuanhao','passwd':'123'}, 6 {'name':'病毒尖er','passwd':'123'}, 7 ] 8 current_user={'username':None,'login':False} 9 def auth(auth_type="file"): 10 def auth_func(func): # 用戶登錄驗證 11 def bar(*args,**kwargs): 12 if auth_type == "file": 13 if current_user["username"] and current_user["login"]: 14 res = func(*args,**kwargs) 15 return res 16 for i in range(3): # 給用戶三次重複輸入的機會 防止進入其它功能進入下一層 17 username = input("請輸入用戶名:").strip() 18 passwd = input("請輸入密碼:").strip() 19 for item in user_list: 20 if username == item["name"] and passwd == item["passwd"]: 21 current_user["username"] = username 22 current_user["login"] = True 23 res=func(*args,**kwargs) 24 return res 25 else: 26 print("您輸入的用戶名或者密碼有誤") 27 elif auth_type == "ldap": 28 print("快點告訴你,你用我畫的蠟筆") 29 res = func(*args,**kwargs) 30 return res 31 return bar 32 return auth_func 33 @auth(auth_type="file") 34 def index(): 35 print("歡迎來到京東商城" ) 36 @auth(auth_type="ldap") # 傳參數 類型對應 37 def home(name): 38 print("%s歡迎回家" %name) 39 @auth(auth_type="file") 40 def shop_car(name): 41 print("%s的購物車是空的,趕忙購物咯" %name) 42 43 index() 44 home(current_user["username"]) 45 shop_car(current_user["username"])