定义
本质就是函数,功能 为其它函数添加附加功能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"])