- 装饰器本质
装饰器本质就是一个修饰其他函数的函数,为其他函数添加附加功能
- 装饰器要把握的2个原则
1.不修改被修饰函数的源代码 2.不修改被修饰函数的调用方式
- 装饰器的实现
装饰器 = 高阶函数+函数嵌套+闭包
满足下面任何一个条件都是高阶函数: (1)函数接收的参数是一盒函数名 (2)函数的返回值是一个函数名
函数嵌套:父函数里面还有子函数 闭包:作用域的一种体现,一层套一层(一层一个函数),给最外层传一个参数,可以一直渗透到最里层
只用高阶函数例子:给函数加上统计运行时间的功能
import time
def foo():
print("你好")
def test(func
):
start_time
= time
.time
()
print(func
)
func
()
stop_time
= time
.time
()
print("函数%s的运行时间为%s;但是函数调用方式从foo()变成了test(foo)" % (func
.__name__
, stop_time
-start_time
))
test
(foo
)
import time
def foo1():
print("你好")
def test1(func
):
start_time
= time
.time
()
print(func
)
func
()
stop_time
= time
.time
()
print("函数%s的运行时间为%s;但是函数调用方式从foo()变成了test(foo)" % (func
.__name__
, stop_time
-start_time
))
return func
foo1
= test1
(foo1
)
foo1
()
高阶函数+函数嵌套实现基本的装饰器架子
def func():
pass
def timmer(func
):
def wrapper():
func
()
return wrapper
func
= timmer
(func
)
func
()
高阶函数+函数嵌套实现基本的装饰器:给函数加上统计运行时间的功能
import time
def func():
print("in func")
time
.sleep
(2)
def timmer(func
):
def wrapper():
start_time
= time
.time
()
func
()
stop_time
= time
.time
()
print("函数%s的运行时间为%s;但是函数调用方式从foo()变成了test(foo)" % (func
.__name__
, stop_time
-start_time
))
return wrapper
func
= timmer
(func
)
func
()
- 装饰器优化:带参数和返回值的装饰器
'''
func = timmer(func)
func(1,2,3)
func=timmer(func)的返回值是wrapper函数,给func加参数等价于给wrapper加参数
所以func(*args, **kwargs) => wrapper(*args, **kwargs)
func的返回值要在wrapper中接收一下,再return回去
'''
def timmer(func
):
def wrapper(*args
, **kwargs
):
start_time
= time
.time
()
print(func
)
res
= func
(*args
, **kwargs
)
stop_time
= time
.time
()
print("%s函数运行时间为%s" % (func
.__name__
, stop_time
-start_time
))
return res
return wrapper
def func(*args
, **kwargs
):
time
.sleep
(1)
print(args
, kwargs
)
print("in func")
func
= timmer
(func
)
res
= func
(1,2,3)
print(res
)
- 修改成@的方式
def timmer(func
):
def wrapper(*args
, **kwargs
):
start_time
= time
.time
()
res
= func
(*args
, **kwargs
)
stop_time
= time
.time
()
duration
= stop_time
-start_time
print("%s函数运行时间为%s" % (func
.__name__
, duration
))
return res
return wrapper
@timmer
def func(*args
, **kwargs
):
time
.sleep
(1)
print("in func")
print(args
, kwargs
)
return (args
, kwargs
)
print(func
(1, 2, 3))
- 带参数的装饰器–实现认证类型选择
def auth(auth_type
="file_auth"):
def dec_auth(func
):
def wrapper(*args
, **kwargs
):
print("你输入的认证类型是%s" % auth_type
)
username
= input("用户名:").strip
()
passwd
= input("密码:").strip
()
if username
== "root" and passwd
== "123":
res
= func
(*args
, **kwargs
)
return res
else:
print("用户名密码错误")
return wrapper
return dec_auth
@auth
(auth_type
="db_auth")
def car(name
):
print("欢迎来到%s的购物车"%name
)
car
("ybp")