闭包函数:满足两点的函数都是闭包函数
1.定义在函数内部的函数
2.函数内部引用了外部函数作用域的名字
# 用闭包的方式给函数体传参: def outter(x,y): # 第三步,用另外一个函数将内层封装起来 # x = 1 # 第二步,在函数my_max外部引用外部函数作用域名 # y = 2 def my_max(): #第一步,给函数传参 if x > y : return x return y return my_max res = outter(1,2) # 返回的是x = 1, y = 2 时函数my_max()的函数名指向的函数体地址 print(res()) # 2 间接调用函数my_max(),并将结果返回值打印出来
装饰器:
原则:开放封闭,对扩展开放,对修改封闭
此外,装饰器不能改变被装饰对象源代码,不能改变被装饰对象调用方式
# 补充知识点 import time # 导入时间模块 print(time.time()) # 时间戳,表示当前时间距离1970-1-1 00:00:00相差的秒数 # 1970-1-1 00:00:00是Unix诞生的元年 time.sleep(3) # 表示让cpu睡眠三秒,程序暂停三秒
#例子:统计index函数执行的时间 import time def index(): time.sleep(2) print('cvnifdhivusn') start = time.time() index() end = time.time() print('index run time:%s'%(end-start)) # 结果cvnifdhivusn # index run time:2.000300168991089 休息了2秒,执行速度很快
# 装饰器简单版本 import time def index(): time.sleep(3) print('hiuehfjarh') def outter(func): # func = 最原始的index函数的内存地址 def get_time(): start = time.time() func() end = time.time() print('index run time:%s'%(end-start)) return get_time res = outter(index) # outter(index) = get_time 返回的是get_time函数的内存地址 index = res # 再将返回的内存地址赋值给变量index,做到以假乱真,调用方式不变的要求 index() # 结果:hiuehfjarh index run time:3.0003960132598877
装饰器语法糖:会将紧挨着它的可调用对象的名字当作参数自动传入调用outter
@outter # outter(index) def index(): pass
装饰器模板:
def outter(func): def inner(*args,**kwargs): print(' ') # 执行被装饰函数之前,可以做的操作 res = func(*args,**kwargs) print(' ') # 执行被装饰函数之后,可以做的操作 return = res return = inner
# 例子:认证装饰器 # 执行函数index之前必须先输入用户名和密码,正确之后才可以执行操作 # 否则提示用户输入错误,结束程序 user_dic = {'is_login':None} def login_auth(func): def inner(*args,**kwargs): if user_dic['is_login']: # 布尔值为False res = func(*args,**kwargs) return res else: username = input(':').strip() password = input(':').strip() if username == 'zhao' and password == '123': user_dic['is_login'] = True # 账号及密码都正确则布尔值变为True res = func(*args,**kwargs) # 执行函数func()并将结果用res接收 else: print('username or password error') return inner
多层装饰器:
装饰器在装饰的时候,顺序从下往上
装饰器在执行的时候,顺序从上往下