装饰器
什么是装饰器
一种为其他函数增加新功能的函数就是装饰器
装饰器基于闭包函数实现
器,指的就是一种工具,例如生活中,打孔器
装饰,指的是给某个已存在的对象添加装饰品
装饰的目的是为了给这个被装饰对象,提加新功能或者说增加某种功能
实际开发时,用的最多的就是将一段公共代码提取到装饰器
登陆验证这个功能每个其他函数在执行前都需要这么一段验证的代码就可以定义为装饰器
在程序中工具就是函数
如此一来,装饰器指的就是一个函数,被装饰者也是一个函数
总结:装饰器在遵循开闭原则的前提下,扩展新功能,就是用一个函数去扩展另一个已存在的函数的功能
装饰器中使用到的知识点:
闭包 函数对象 名称空间作用域 语法糖 函数嵌套
扩展性是对一个应用程序来说非常重要的能力,任何应用程序都需要扩展,于是出现了开闭原则
开闭原则
对修改关闭,对扩展开放
不允许修改源代码以及调用方式
装饰器就是一种可以保证不修改源代码,也不修改调用方式,还能给函数添加新功能的方式
原下载计时需求
import time
#下载功能
def download():
boot_time=time.time()
print('start')
time.sleep(3)
print ('finish')
print(time.time()-boot_time)
download()
测试二
boot_time=time.time()
download()
print(time.time()-boot_time)
测试三
def run_time(func)
boot_time=time.time()
func()
print(time.time()-boot_time)
run_time(download)
#修改了调用方式
def outer(func):
def run_time()
boot_time=time.time()
func()#这是执行原始的download函数 也是被装饰的函数
print(time.time()-boot_time)
return run_time
download=outer(download)
download()
装饰器模板
import time
#原始函数
def test():
print('test run')
#记录执行时间的装饰器
def outer(func):
def wrapper():
新功能
func()
return wrapper
test = outer(test)
test()
1.无参装饰器
def outer(func):
def wrapper(*args,**kwargs):
#实现的功能 (添加的新功能)
res=func(*args,**kwargs)
return res
return wrapper
import time
def download():
print('download run!')
#=======================================
def outer(func):
def run_time(*args,**kwargs):#为了让装饰器能接受任何形式任何长度的参数
boot_time = time.time()
res=func(*args,kwargs)#将参数原木原样交给被装饰着
print(time.time()-boot_time)
return res#把原始函数的执行结果交给调用者
return run_time
download=outer(download)
========================================
# 使用者
download()
装饰器的语法糖:就是一种简便写法,使你的语法更简洁
提供输出日记(日志 什么时候干了什么事)功能
def logger(func): *************
def wrapper(*args,**kwargs):
print('时间:%s func'%(time.time(),func._name_))
res=func(*args,**kwargs)
return res
return wrapper
@logger(该语法就可以帮你完成 对原始函数的伪装)
注意1 必须写在被装饰函数的正上方
注意2 在开发时要注意装饰器必须写在被装饰函数之上
def login():
print('登陆成功..')
login()
@timer#logger=timer(logger)
@logger#login=logger(login)
在嵌套多个装饰器时,执行的顺序是 从上往下一次调用,结束的顺序反过来,是从下往上
实际开放中没什么用
2.有参装饰器
def have_agrs(arg):
def outer(func):#func要被装饰的函数
def inner(*args,**kwargs):
代码块
:return:
res = func(*args,**kwargs)
代码块
return res
return inner
return outer
转载于:https://www.cnblogs.com/gengbinjia/p/10276926.html