装饰器的概念
装饰器的实现是函数里面嵌套函数;
装饰器的本质是一个函数, 它可以让其他函数在不需要做任何代码改动的前提下增加额外的功能,即想要增强原有函数的功能,但不希望修改now()函数的定义;
装饰器需要传递一个函数, 返回值也是一个函数对象.
eg:在程序执行之前写祝福语,在程序执行之后打广告:
def desc(fun): #1). 需要传递一个函数, 要装饰的函数 fun=login()
def add_info(): # 2). 装饰器函数里面嵌套函数
print(“祝您幸福!”)
fun() # login()
print(“欢迎再次使用”)
return add_info #3). 返回值是嵌套的函数对象
语法糖
@desc # login = desc(login) # 4). 如何调用装饰器(两种方式),返回值是一个函数。
def login():
print(“login…”)
login() #此时的login()是add_info()
装饰器的应用场景
计时器
import time
def timeit(fun): #fun=add()
def wrapper(*args, **kwargs): # 接收可变参数和关键字参数
# args: 元组 kwargs: 字典
# 函数执行之前
start_time = time.time()
# 执行函数
res=fun(*args, **kwargs) # 对于元组解包, 对于字典解包,并且将add的返回值给res
# 执行函数之后
end_time = time.time()
print("运行时间为:%.6f" % (end_time - start_time))
return res
return wrapper
@timeit
def add(a,b):
time.sleep(3)
return a+b
print(add(1,3)) #实际执行wrapper,并把wrapper的返回值打印
记录日志
import functools
import time
def add_log(fun):
@functools.wraps(fun) #可以保留被装饰函数名和帮助文档信息
def wrapper(*args, **kwargs):
run_time = time.ctime() #日志的时间
fun_name = fun.__name__ #函数名称
start_time = time.time()
res = fun(*args, **kwargs)
end_time = time.time()
print("[%s] 函数名: %s, 运行时间:%.5f, 运行返回值结果:%d"
%(run_time, fun_name, end_time-start_time, res )
)
return res
return wrapper
@add_log
def add(x,y):
'''
这是求和函数
'''
time.sleep(0.1)
return x+y
print(add(1,2))
print(add.__doc__)
用户登陆验证
import functools
login_users = [‘admin’, ‘root’]
def is_login(fun): # fun: writeBlog
@functools.wraps(fun)
def wrapper(*args, **kwargs): # name=“admin” # kwargs={“name”:“admin”}
# 判断写博客的这个用户是否登陆成功;
if kwargs.get(“name”) in login_users:
res = fun(*args, **kwargs)
return res
else: #如果没有登陆成功,就跳转到登陆界面
res=login()
return res
return wrapper
必须登陆成功
@is_login # writeBlog = is_login(writeBlog)
def writeBlog(name):
return “编写博客”
def login():
return “登陆。。。。”
是否登陆成功都可以执行代码
def news():
print(“新闻…”)
print(writeBlog(name=“admin1”))
函数参数验证
import functools
def required_ints(fun):
@functools.wraps(fun)
def wrapper(*args, **kwargs): # args=(1,2)
for i in args:
if not isinstance(i , int):
print("函数所有参数并非为整形")
break
else:
res = fun(*args, **kwargs)
return res
return wrapper
@required_ints
def add(a, b):
return a + b
print(add(1,2))
带有多个装饰器的函数
当有多个装饰器时, 从下到上调用装饰器,
真实wrapper内容执行是从上到下执行.
eg:
def makebold(fun):
print("bold1")
def wrapper1(*args, **kwargs):
print("bold2")
return fun(*args, **kwargs) # wrapper
return wrapper1
def makei(fun): # fun=login
print("i1")
def wrapper(*args, **kwargs):
print("i2")
return fun(*args, **kwargs)
return wrapper
@makebold # login = makebold(login) # login为wrapper1
@makei # login = makei(login) # login为wrapper
def login():
return "登陆"
print(login())
带有参数的装饰器
import functools
import time
def log(kind): # kind="debug" kind为参数
def add_log(fun):
@functools.wraps(fun)
def wrapper(*args, **kwargs):
start_time = time.time()
res = fun(*args, **kwargs)
end_time = time.time()
print("<%s> [%s] 函数名: %s, 运行时间:%.5f, 运行返回值结果:%d"
%(kind, time.ctime(), fun.__name__, end_time-start_time, res )
)
return res
return wrapper
return add_log
@log("debug")
#log("debug")==> 返回值是add_log
#add=add_log(add)
def add(x,y):
time.sleep(0.1)
return x+y
add(1,2)