定义:函数内部函数对外部做用域而非全局做用域的引用闭包
使用参数app
def func(x) print(x) func(1) func(1)
1 1
def outter(x) def inner() print(x) return inner f = outter(1) f()
1
闭包的意义:返回的函数对象,不单单是一个函数对象,在该函数外还包裹了一层做用域,这使得,该函数不管在何处调用,优先使用本身外层包裹的做用域。函数
import requests def outter(url): def get(): response = requests.get(url) print(f'done:{url}') return get baidu=outter('https:www.baidu.com') baidu()
done: https://www.baidu.com
装饰器指:未被装饰器对象添加额外的功能。url
注意:1,装饰器自己实际上是能够任意可调用的对象code
2,被装饰的对象能够是任意可调用的对象对象
为何须要装饰器ip
若是咱们已经上线了一个项目,咱们须要修改某一个方法,可是咱们不想修改方法的使用方法,这个时候能够使用装饰器。由于软件的维护应该遵循开放封闭原则,即软件一旦上线运行后,软件的维护对修改源代码是封闭的,对扩展功能指的是开放的。作用域
注意:1,不修改被装饰对象的源代码get
2,不修改被装饰对象的调用方式
怎么用装饰器
传参方式:改变调用方式
传参方式:包给函数——外包
mport time def time_count(func): # func = 最原始的index def wrapper(*args, **kwargs): start = time.time() res = func(*args, **kwargs) end = time.time() print(f"{func} time is {start-end}") return res return wrapper @time_count # home = time_count(home) def home(name): print(f"welcome {name} to home page") time.sleep(1) return name @time_count # index = time_count(index) def index(): print('welcome to index') time.sleep(1) return 123 res = home('egon') print(f"res: {res}")
welcome egon to home page <function home at 0x102977620> time is -1.0005171298980713 res: egon
def deco(func): def wrapper(*args,**kwargs) res = func(*args,**kwargs) return res return wrapper
is_login_dict = {'username':None} def login_deco(func): def wrapper(*args,**kwargs): if not is_login_dict['username']: username = input('请输入你的用户名').strip() if username != 'john': print('非法输入') return is_login_dict['username']=username res = func(*args,**kwargs) return res else: res = func(*args,**kwargs) return res return wrapper @login_deco def withdraw(): print('from withdraw') withdraw() withdraw() withdraw()
有参装饰器
is_login_dict = {'username': None} def auth(origin): def login_deco(func): def wrapper(*args, **kwargs): # 赋值后的time_sleep if origin == 'file': if not is_login_dict['username']: username = input('请输入你的用户名》》》').strip() if username != 'fanping': print('非法登陆') return is_login_dict['username'] = username res = func(*args, **kwargs) # 真正的time_sleep return res else: res = func(*args, **kwargs) # 真正的time_sleep return res elif origin == 'mongodb': print('非法登陆') else: print('dsb') return wrapper return login_deco # f = origin('file') # login_deco # shopping = f(shopping) # shopping() @auth('file') def shopping(): print('from shopping') @auth('mongodb') def withdraw(): print('from withdraw')
注意:装饰器给函数增长功能吗,可是不改变函数内部的语法,不改变函数调用方式