一、闭包函数
定义:定义在函数内部的函数引用了外部函数作用域的名字
第一种 def outter(): x = 1 def index(): print(x) return index res = outter() print(res) res() # 1 利用函数的返回值将函数的值打印出来 # 首先执行定义函数outter然后执行调用函数outter,接下来执行x=1,接着执行闭包函数index,然后return返回index这个函数,就相当于一个变量名, #返回到outter这个调用函数,打印出的结果是index这个函数的id地址 # <function outter.<locals>.index at 0x000001F485AD0AE8> 第二种 def outter(): x = 1 def index(): print(x) return index res = outter() def func(): # 如果下面在加一个函数,它的值还是为1,因为函数在定义阶已经固定,与调用位置无关 x = 333 res() func()
如图,此图为闭包函数的操作顺序
给函数体传值得两种方式
第一种:传参
def index(username): print(username) # 直接通过参数传给函数
第二种:利用必包的形式
def outter(x,y): def my_max(): if x > y: return x return y return my_max res1 = outter(1,40) # res1就是my_max函数的地址 print(res1()) # 打印结果为40 res2 = outter(20,30) print(res2()) # 打印结果为30 # 利用闭包函数,首先在定义函数my_max里输入两个形参, # 然后调用函数outter里的实参值可以传入定义函数的形参中,在闭包函数中进行比较
二、装饰器
定义:装饰器就是给被装饰对象增加新功能的的一个工具
开放封闭原则:通俗来讲,就是在修改一个项目的需求时,需要给它添加某个或某些功能,但是它的源代码不能更改
装饰器必须遵循的两个原则
1.不改变被装饰多想的源代码
2.不改变被装饰对象(可调用对象)的调用方式
装饰器在装饰的时候 顺序从下往上
装饰器在执行的时候 顺序从上往下
1.import time模块
print(time.time())
1562812014.731474 # 时间戳 当前时间距离1970-1-1 00:00:00相差的秒数
1970-1-1 00:00:00是Unix诞生元年
time.sleep(1) # 表示让cpu停止(休息)1秒
装饰器的简单版 import time def inner(): time.sleep(2) print('您好!') inner() # 会在两秒之后打印“您好!” #cpu运行的速度非常快,所以代码与代码之间运行的速度非常的快,如果中间需要读取一个文件 # 那么可能会还没读完这个文件,就会运行下面的代码, #所以可以让cupc中途休息两秒,就可以读取完文件 start = time.time() inner() end = time.time() print('inner run time:%s'%(end-start)) # inner run time:2.000295400619507 # inner的执行时间
2.装饰器的模板
无参函数 from functools import warps def outter(func): @warps(func) def inner(*args,**kwargs): # 在形参中使用 '执行被装饰函数之前你可以做得操作' res = func(*args,**kwargs) # 在实参中使用 '执行被装饰函数之后你可以做得操作' return res return inner 有参函数 from functools import warps def warppers[date]: date = 'file' def outter[func]: @warps(func) def inner[*args,**kwargs]: if date == 'file': res = func(*args,**kwargs) return res return inner() return outter
3.装饰器语法糖
注意:
语法糖在书写的时候应该与被装饰对象紧紧挨着,两者之间不能有空格
紧挨着下面可调用对象的名字自动当做它的参数传入
def outter(func): # func = 最原始的index函数的内存地址 def get_time(*args, **kwargs): start = time.time() res = func(*args, **kwargs) end = time.time() print('func run time:%s'%(end-start)) return res return get_time @outter # index = outter(index) outter(最原始的index的函数的内存地址) def index(): time.sleep(3) print('您好!') return 'index
4.认证装饰器
执行函数index之前,必须输入用户名和密码,正确之后才能执行index
否则提示用户输入错误,结束程序
def auth(func): # func=index def wrapper(*args,**kwargs): if current_user['username']: print('已经登陆过了') res=func(*args,**kwargs) return res uname=input('用户名>>: ').strip() pwd=input('密码>>: ').strip() if uname == 'egon' and pwd == '123': print('登陆成功') current_user['username']=uname res=func(*args,**kwargs) return res else: print('用户名或密码错误') return wrapper @auth #index=auth(index) def index(): time.sleep(1) print('welcome to index page') return 122 @auth def home(name): time.sleep(2) print('welcome %s to home page' %name) index() home('egon')
5.装饰器修复技术
用户查看被装饰函数的函数名的时候查看到的就是被装饰函数本身
用户查看被装饰函数的注释的时候查看到的就是被装饰函数的注释
from functools import wraps def outter(func): @wraps(func) # 装饰器修复技术 def inner(*args,**kwargs): """ inner函数 :param args: :param kwargs: :return: """ print('执行被装饰函数之前 你可以执行的操作') res = func(*args,**kwargs) print('执行被装饰函数之后 你可以执行的操作') return res return inner
5.装饰器应用场景
1.引用日志
2.函数执行时间统计
3.执行函数前预备处理
4.执行函数后清理功能
5.权限校验
6.缓存