python之装饰器
高阶函数,返回值是一个函数(定义函数并不会执行函数的内容,调用时才会执行)
1.有小题如下
2
2.创建装饰器
# 创建装饰器,要求如下:
# 创建add_log装饰器,被装饰的函数打印日志信息;
# 日志格式为:字符串时间 函数名;运行时间;运行返回值结果
import time
import functools
def add_log(fun): 装饰器
@functools.wraps(fun) 调用模块
def wrapper(*args,**kwargs): 接受可以是变量 也可以是关键字函数
ctime=time.ctime()
funname=fun.__name__
starttime = time.time()
res=fun(*args,**kwargs) 装饰函数,在此处返回原函数并执行
endtime=time.time()
print("[%s] 函数名:%s 运行时间为:%.6f 运行返回结果:%s" % (ctime,funname,endtime - starttime,res))
return res
return wrapper
@add_log
def logmessags():
return 'hello world'
logmessags()
执行结果如下:
3.函数有返回值的解决办法
import random 导入随机数模块
import time 导入时间模块
import string 导入字符串模块
import functools
li=[random.choice(string.ascii_letters) for i in range(1,100) ] 随机挑选100个字母
def timeit(fun): # con_add
@functools.wraps(fun) ##保留被装饰函数的函数名和帮助文档信息
def wrapper(*args,**kwargs):###接收可变参数和关键字参数
# 函数执行前
starttime = time.time()
# 执行函数
res=fun(*args,**kwargs)##args解包
# 函数执行后
endtime = time.time()
print("运行时间为:%.6f" % (endtime - starttime))
return res
return wrapper
@timeit
def con_add():
s = ''
for i in li:
s += (i+",")
print(s)
con_add()
@timeit
def join_add():
print(",".join(li))
join_add()
@timeit
def con_list(n):
print([i*2 for i in range(n)])
con_list(20)
@timeit
def con_map(n):
return list((map(lambda x:x*2 , range(n))))
print(con_map(20))
实验如下
4.在装饰器里函数中嵌套函数
# 解决问题:1.在函数执行之前和之后添加功能,调用函数的方式改变了
#2.不改变原有函数的调用方法:函数里面嵌套函数,并且返回嵌套的函数
def desc(fun): # fun=login 需要传递一个函数,即要装饰的函数
def add_info(): ###装饰器函数里面嵌套函数
print('hello')
fun() ###login()
print('welcome')
return add_info ##3返回值是嵌套函数
def login():
print('login...')
login=desc(login) ###返回值是一个函数
login()
5.用户登录装饰器
需求:用户登录验证的装饰器
1)如果用户登陆成功,则执行被装饰的函数
2)如果用户登陆不成功,则执行登陆函数
import functools
login_users=['root','admin']
def is_login(fun): # fun: writeBlog
@functools.wraps(fun)
def wrapper(*args, **kwargs): name="admin" kwargs={"name":"admin"} 判断写博客的这个用户是否登陆成功
news( )
if kwargs.get("name") in login_users:
res = fun(*args, **kwargs)
return res
else:
res=login()
return res
return wrapper
@is_login
必须登陆成功
def writeBlog(name):
return 'write'
def login():
return 'please login in'
是否登陆成功均可进入
def news():
print('news/。。。')
print(writeBlog(name='admin'))
6.无参数的装饰器
# 编写装饰器required_ints,条件如下:
# 1)确保函数接到的每一个参数均为整数
# 2)如果参数不是整形数,打印TypeError:参数必须为整形
import functools
def required_ints(fun):
@functools.wraps(fun)
def wrapper(*args, **kwargs):
for i in args: i 在变量中遍历
if not isinstance(i,int): 如果i 不是整形
return 'TypeError: 参数必须为整形'
break
else:
res=fun(*args,**kwargs)
return res
return wrapper
@required_ints
def add(a,b):
return a+b
print(add(1,6) )
print(add(1,1.0))
@required_ints
def Max(a,b,c,d):
return max(a,b,c,d) #返回a,b,c,d中的最大值
print(Max(1,2,3,4))
7.有参数的装饰器(升级版)
import functools
def required_types(*kinds): 在原有装饰器前再定义一个函数,此时要求如果不是整形或浮点型则
def required(fun): 报错,否则执行之。
@functools.wraps(fun)
def wrapper(*args,**kwargs):
for i in args:
if not isinstance(i,kinds)
return('Error')
else:
res=fun(*args,**kwargs)
return res
return wrapper
return required
@required_types(int,float)
def add(a,b):
return a+b
print(add(1,2.0))
print(add(2+2j))
结果为:3.0
结果为:Error