一.装饰器
本文分为一下几点
- 装饰器介绍
- 装饰器语法糖
- 装饰器的函数的返回值
- 保留被装饰的函数的函数名和帮助文档信息
- 装饰器中不同条件下执行不同的函数
- 多个装饰器
- 带有单参装饰器
1.装饰器介绍
装饰器就是对被装饰的对象(函数、类)进行重构的,其可以在不改变原来对象的情况下调用对象时执行重构后的行为
1.解决问题:在函数执行之前和执行之后添加功能,调用函数的方式改变了
2.不改变原有函数的调用方法:函数里面嵌套函数,并且返回嵌套的函数
2.装饰器语法糖
在Python中,可以使用”@”语法糖来精简装饰器的代码,把 decorator 置于函数的定义处,免去给函数重新赋值( 即function = decorator(funtion))
使用实例说明
import functools #functools 标准库
import time #time 时间函数
def add_log(fun):
@functools.wraps(fun) #不用此模块add(x,y)函数的__name__,__doc__都会丢失
def wrapper(*args,**kwargs): #*args为元组 **kwargs为字典
start_time = time.time()
res = fun(*args,**kwargs)
end_time = time.time()
print("[%s] 函数名:%s, 运行时间 :%.5f ,运行返回值:% d"
%(time.ctime(),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))
3.装饰的函数的返回值
def timeit(fun):
def wrapper(*args,**kwargs): #接收可变参数和关键字参数
#args:元组 kwargs:字典 args=(5,)
#原函数执行之前
start_time = time.time()
#执行函数
res = fun(*args,**kwargs) #args解包
#执行函数
end_time = time.time()
print("运行时间为:%.6f" % (end_time - start_time))
return res
return wrapper
@timeit
def list_create(n):
return(i*2 for i in range(n)])
@timeit
def map_create(n):
return(list(map(lambda x:x*2,range(n))))
list_create(5)
map_create(5)
print(list_create(100)) ##wrapper(100)
4.装饰器中保留被装饰函数的名字及文档信息
import functools
def timeit(fun):
"""这是一个装饰器timeit"""
@functools.wraps(fun) ##内置装饰器
可以保留被装饰的函数的函数名和帮助文档信息
def wrapper(*args,**kwargs): #接收可变参数和关键字参数
"""这是一个wrapper函数"""
#args:元组 kwargs:字典 args=(5,)
#原函数执行之前
start_time = time.time()
#执行函数
res = fun(*args,**kwargs) #args解包
#执行函数
end_time = time.time()
print("运行时间为:%.6f" % (end_time - start_time))
return res
return wrapper
@timeit
def fun():
print("hello")
print(fun_list.__name__)
print(fun_list.__doc__)
5.多个装饰器
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
# 当有多个装饰器时,从上到下调用装饰器
# 真实wrapper内容执行是从上到下执行
@makebold #login = makebold(login) #login为wrapper1
@makei #login = makei(login) #login为wrapper
def login():
return "登陆"
print(login())
6.带有单参装饰器
综合上面总结代码在一个程序上汇总以上知识点儿
import datetime
import time
def check(sec):
def inc(dest):
dest.__name__=sec.__name__
dest.__doc__=sec.__doc__
print(dest.__name__,dest.__doc__)
print(dest)
return dest
return inc
def wraps(durang):
def wraps(fn):
@check(fn)#----------此处为单参装饰器
def wrapsd(*args,**kwargs):
'''xiaoliuchangzuimei''
start=datetime.datetime.now()
set=fn(*args,**kwargs)
derta=(datetime.datetime.now()-start)
if durang>5:
print(durang)
return set,derta
return wrapsd
return wraps
@wraps(5)
def add(x,y):
'''xiaohuihuizuishuai'''
time.sleep(5)
return x+y
二.functiontools
1.functiontools.partial(偏函数)
- 偏函数,把函数部分的参数固定下来相当于为部分的参数添加一个固定的默认值,返回一个新的函数
- 从partial生成新的函数,是对原函数的封装
import functools
def add(x,y)->int
return x+Y
newadd=functools.partial(add,y=5)
print(newadd(7))
2.reduce方法
*reduce 方法,顾名思义就是减少
*reduce(function,sequence[,inital ])->value
- 可迭代对象泵为空,初始值没提供就在可迭代对象中去一个元素
form functools import reduce
nums=[6,9,7,8,5,4]
print(nums)
print(sum(nums))
print(reduce (lambda val,x:val+x,nums))
# 感谢大家支持:
欢迎志同道合的朋友:成为小灰灰的朋友