1.闭包函数
定义在函数内部的函数,引用了外部函数作用域的名字,主要满足上面的两点都叫做闭包函数。
def outer(x,y): def my_max(): if x > y: return x return y return my_max res = outer(32,53) # res就是my_max函数的内存地址 print(res()) # 53
import requests def outer(url): # 给函数传参 def my_get(): response = requests.get(url) if response.status_code == 200: print(len(response.text)) # 92760 return my_get my_jd = outer('https://www.jd.com') my_jd()
2.装饰器
装饰器是用来给装饰对象添加新功能的工具
装饰器的开放封闭原则:
开放:对扩展功能开放
封闭:对原有功能的修改封闭
特点:
1.不能改变装饰对象的源代码
2.不改变被装饰对象的调用方式
装饰器应用场景
简单注册表
funcs = [] def register(func): funcs.append(func) return func @register # register(a) def a(): return 3 @register # register(b) def b(): return 5 # 访问结果 result = [func() for func in funcs]
import time print(time.time()) # 1562833711.367552 时间戳(距离1970.1.1 0点相差秒数) time.sleep(3) # cpu运行停止三秒
import time def index(): time.sleep(3) print('哈哈') # 哈哈 def outer(func): # func = index原始的index函数的内存地址 def get_time(): start = time.time() func() # func() = index() 调用 end = time.time() print('index run time:%s'%(end-start)) # index run time:3.000720500946045 return get_time index = outer(index) # index指向get_time函数的内存地址 index()
import time def index(): time.sleep(3) print('哈哈') # 哈哈
return 'index' def login(name): time.sleep(1) print('%s'%name) # egon return 'login' def outer(func): # 最原始的login/index函数内存地址 def get_time(*args,**kwargs): # args = {'egon',} kwargs {} start = time.time() res = func(*args,**kwargs) # 最原始的login/index函数内存地址 end = time.time() print('index run time:%s'%(end-start)) # index run time:1.000943899154663 index run time:3.0001919269561768 return res return get_time login = outer(login) # 括号里的是最原始的login函数内存地址,前面的是变量名 res = login('egon') index = outer(index) # # 最原始的index函数内存地址 res = index()
import time def outer(func): def get_time(*args,**kwargs): start = time.time() res = func(*args,**kwargs) end = time.time() print('index run time:%s'%(end-start)) # index run time:3.0018677711486816 index run time:1.0005810260772705 index run time:1.0004172325134277 return res return get_time @outer # index = outer(index) def index(): time.sleep(3) print('哈哈') # 哈哈 return 'index' @outer def login(name): time.sleep(1) print('%s'%name) # egon return 'login' @outer def home(*args,**kwargs): time.sleep(1) return'home' index() login('egon') home()
装饰器模板 outer(func): def inner(*args,**kwargs): print('执行被装饰函数之前能够做的操作') res = func(*args,**kwargs) print('执行被装饰之后,能够做的操作') return res return inner
认证装饰器
执行函数index之前必须先输入用户名和密码 正确之后才能执行index,否则提示用户输入错误 结束程序
import time user_dic = {'is_login':None} def login_auth(func): def inner(*args,**kwargs): if user_dic['is_login']: res = func(*args,**kwargs) return res else: username = input('please input your username>>>:').strip() password = input('please input your password>>>:').strip() if username == 'jason' and password == '123': user_dic['is_login'] = True res = func(*args,**kwargs) return res else: print('username or password error') return inner @login_auth def index(name): time.sleep(1) print('%s is dsb'%name) # egon is dsb return 666 @login_auth def home(): time.sleep(1) print('home') # home return 999 index('egon') print(index) # <function login_auth.<locals>.inner at 0x000002811B4A8A60> home() print(home) # <function login_auth.<locals>.inner at 0x000002811B4A8B70>
1.无参装饰器 from functools import wraps def outter(func): @wraps(func) # index = wraps(inner) def inner(*args,**kwargs): # * **在形参中使用 # 执行被装饰函数之前你可以做的操作 res = func(*args,**kwargs) # * **在实参中使用 # 执行被装饰函数之后你可以做到操作 return res return inner @outter # index = outter(index) def index(username,*args,**kwargs): """index注释""" pass print(index)
2.有参装饰器(最复杂就三层) def wrappers(data): # data = 'file' def outter(func): def inner(*args,**kwargs): if data == 'file': # 执行被装饰函数之前你可以做的操作 res = func(*args,**kwargs) # * **在实参中使用 # 执行被装饰函数之后你可以做到操作 return res return inner return outter