闭包函数
定义:函数内部函数对外部作用域而非全局作用域的引用
两张函数参数的方式
-
使用参数
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
装饰器
装饰器指:未被装饰器对象添加额外的功能。
注意:1,装饰器本身其实是可以任意可调用的对象
2,被装饰的对象可以是任意可调用的对象
为什么需要装饰器
如果我们已经上线了一个项目,我们需要修改某一个方法,但是我们不想修改方法的使用方法,这个时候可以使用装饰器。因为软件的维护应该遵循开放封闭原则,即软件一旦上线运行后,软件的维护对修改源代码是封闭的,对扩展功能指的是开放的。
注意:1,不修改被装饰对象的源代码
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')
注意:装饰器给函数增加功能吗,但是不改变函数内部的语法,不改变函数调用方式