python中装饰器的原理以及实现,
python版本 3.6
1.python的装饰器说白了就是闭包函数的一种应用场景,在运用的时候我们遵循
#开放封闭原则:对修改封闭,对拓展开放
2.什么是装饰器
#装饰他人的器具,本身可以是任意可调用的对象,被装饰者也可以是任意可调用对象
#装饰器的原则:1.不可修改被装饰对象的源代码,2不修改被装饰对象的调用方式
#装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
3.实现装饰器之前先来了解闭包函数
#1.闭包函数 => 函数嵌套+函数对象+名称空间与作用域 #闭:定义是在函数内的函数 #包:该内部函数需要访问一个名字,该名字是属于外层函数作用域的 #闭包函数实现的基本模板 def outter(xxx): def inner() xxx return inner #为函数体传参的两个方案 #1.直接传入参数 #2.在函数体内部定义变量
4.装饰器的实现
#阶段一 #计算一个函数执行的时间 import time def index(): time.sleep(1) print("welcome to my world") start = time.time() index() end = time.time() print("run time is %s" %(end - start)) #修改了装饰对象的源代码 #阶段二 import time def index(): time.sleep(1) print("welcome to my world") def wrapper(): start = time.time() index() end = time.time() print("run time is %s" %(end - start)) #修改了装饰对象的调用方式 #阶段三 import time def index(): time.sleep(1) print("welcome to my world") def wrapper(func): start = time.time() func() end = time.time() print("run time is %s" %(end - start)) wrapper(index) #修改了装饰对象的调用方式 #阶段四: import time def index(): time.sleep(1) print('welcome to index page') def timmer(func): # func=最原始那个index的内存地址 def wrapper(): start=time.time() func() stop=time.time() print('run time is %s' %(stop - start)) return wrapper #把函数作为参数传进去,返回一个函数再去执行,替换返回的函数名为之前传入的函数 index=timmer(index) #index=wrapper的内存地址 index() #wrapper() #这样就没有修改被装饰对象的源代码和调用方式
5.装饰器语法糖
#装饰器语法糖 #在被装饰器对象上方单独一行写:@装饰器的名称 解释器一旦执行到@装饰器的名字就会执行 原函数名 = 装饰器的名字(正下方的那个函数) #修订之后的装饰器 import time def timmer(func): # func=最原始那个index的内存地址 def wrapper(*args,**kwargs): start=time.time()
res=func(*args,**kwargs) stop=time.time() print('run time is %s' %(stop - start)) return res return wrapper @timmer #index=timmer(最原始那个index的内存地址) #index=wrapper的内存地址 def index(): time.sleep(1) print('welcome to index page') index()
6.完善装饰器
#装饰器实现函数,其函数对象的变化,其中包括一些内置的方法__name__,__doc__等等, #这些都是要在被装饰之后返回同样的name,doc 下面我们引入一个第三方包 去实现这些功能 import time from functools import wraps def timmer(func): @wraps(func) def wrapper(*args,**kwargs): start=time.time() #函数返回值 res=func(*args,**kwargs) stop=time.time() print('run time is %s' %(stop - start)) return res # wrapper.__doc__=func.__doc__ # wrapper.__name__=func.__name__ return wrapper # @timmer #index=timmer(最原始那个index的内存地址) #index=wrapper的内存地址 def index(): """ 这是一个index函数 :return: """ time.sleep(1) print('welcome to index page') #上面的引入的第三方包wraps,调用其装饰器帮我们实现了 # wrapper.__doc__=func.__doc__ # wrapper.__name__=func.__name__ 等等这些功能,这样能更好的满足用户的需求
7.上面实现的装饰器是无参装饰器,有参装饰器更新中…………
握不住的沙,干脆扬了它。