- 什么是装饰器?
- 装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
- 为何要用装饰器?
- 开放封闭原则:
- 开放:指的是对拓展功能是开放的
- 封闭:指的是对修改源代码是封闭的
- 装饰器基础知识
- 作用域
- 高阶函数:
- 满足两个条件之一就叫高阶函数:
- 1、函数名可以作为参数输入
- 2、函数名可以作为返回值
- 闭包:
- 如果在一个内部函数里,对在外部作用域(但不是全局作用域)的变量进行引用,那么内部函数就认为是闭包
- 如何用?
#在不改变foo函数及不改变调用方式的情况下,添加统计运行时间的功能
def foo():
print('hello world!!!')
time.sleep(2)
foo()
#解决方案一:失败,修改了源代码
import time
def foo():
start = time.time()
print('hello world!!!')
time.sleep(2)
end = time.time()
print(end - start)
foo()
#解决方案二:失败,修改了调用方式
import time
def foo():
start = time.time()
print('hello world!!!')
time.sleep(2)
end = time.time()
print(end - start)
def show_time():
start = time.time()
foo()
end = time.time()
print(end - start)
show_time()
#解决方案三:失败,将show_time函数做的跟装饰一样,以假乱真。但是每次都需要重新赋值
import time
def show_time(f):
def inner():
start = time.time()
f()
end = time.time()
print('speed %s'%(end-start))
return inner
def foo():
print('hello world!!!')
time.sleep(2)
foo = show_time(foo) #foo指向show_time函数的内存地址
foo()
#解决方案四:语法糖
# 缺点,不同的功能函数,参数可能不一致
import time
def show_time(f):
def inner():
start = time.time()
f()
end = time.time()
print('speed %s'%(end-start))
return inner
@show_time #foo = show_time(foo)
def foo():
print('hello world!!!')
time.sleep(2)
foo()
# 5,最终版
import time
def show_time(f):
def inner(*args,**kwargs):
start = time.time()
f(*args,**kwargs)
end = time.time()
print('speed %s'%(end-start))
return inner
@show_time #foo = show_time(foo)
def foo(id):
print('hello world!!!',id)
time.sleep(2)
def fun01(id,name)
print(f'{id},{name}')
foo(102)
fun01(1,'xwl')