软件面世时,不可能把全部的功能都设计好,再将来的一两年功能会陆续上线,按期更新迭代,软件以前所用的源代码,函数里面的代码以及函数的调用方式通常不会修改,能够在源码不改变的状况下,增长一些新的功能.python
装饰器是以功能为导向的,就是一个函数,在不改变原被装饰的函数的源代码以及调用方式下,为其添加额外的功能.网络
python中装饰器 : 完美的诠释开放封闭原则函数
装饰器就是一个函数 : 他要装饰一个函数,在不改变原函数的源码以及调用方式的前提下,给其增长一个额外的功能优化
import time def index(): time.sleep(2) # 模拟一下网络延迟以及代码的效率 print('欢迎访问博客园主页') def home(name): time.sleep(3) # 模拟一下网络延迟以及代码的效率 print(f'欢迎访问{name}主页') def timer(func): # func = index def inner(): start_time = time.time() func() end_time = time.time() print(f'此函数的执行效率为{end_time-start_time}') return inner index = timer(index) index() # 此为装饰器的雏形,虽然知足了开放封闭原则,可是若是当源代码又返回值时则此代码不够完善.
当须要与原代码返回值一致的时候须要注意一下两点设计
明确源代码的返回值应该返回给谁code
实际返回给了谁源码
如何修改博客
import time def index(): time.sleep(2) # 模拟一下网络延迟以及代码的效率 return '欢迎访问博客园主页' def timer(func): # func = index def inner(): start_time = time.time() ret = func() end_time = time.time() return ret return inner index = timer(index) # inner print(index()) # print(inner()) # 实际的返回值返给了inner,为了让返回值与源代码一致,须要进行赋值操做,这样就保证了返回值一致 # 如今代码已经知足原函数的返回值与装饰器以后的返回值保持一致了,还缺乏的就是传参一致.
当须要与原代码传参保持一致须要注意一下几点class
明确源代码的传参应该传参给谁效率
实际传参给了谁
如何修改
import time def home(name,age): time.sleep(3) # 模拟一下网络延迟以及代码的效率 print(name,age) print(f'欢迎访问{name}主页') def timer(func): # func = home def inner(*args,**kwargs): # 函数定义时,*表明聚合:因此你的args = ('岁月',18) start_time = time.time() func(*args,**kwargs) # 函数的执行时,*表明打散:因此*args --> *('岁月',18)--> func('岁月',18) end_time = time.time() return inner home = timer(home) home('岁月',18) # 这样利用*的打散与聚合的原理,将这些实参经过inner函数的中间完美的传递到给了相应的形参。
代码优化 : 语法糖,Python给咱们提供了一个简化机制,用一个很简单的符号去代替相似home = timer(home)这一句话。
注意 : 由于涉及函数的调用,@timer必定要放在被装饰函数的上方,不然会报错.
def timer(func): # func = home def inner(*args,**kwargs): start_time = time.time() func(*args,**kwargs) end_time = time.time() return inner @timer # 此处代替了home = timer(home) def home(name,age): time.sleep(3) # 模拟一下网络延迟以及代码的效率 print(name,age) print(f'欢迎访问{name}主页') home('岁月',18)
至此标准版的装饰器以下,彻底符合代码开放封闭原则:
def warpter(f): def inner(*args,**kwargs) # 此处执行被装饰函数以前的操做 ret=f(*args,**kwargs) # 此处执行被装饰函数以后的操做 return ret return inner