闭包函数
定义:函数内部函数对外部作用域而非全局作用域的引用
两张函数参数的方式
- 使用参数
def func(x) print(x) func(1) func(1)
1 1
- 包给参数
def outter(x)
def inner()
print(x)
return inner
f = outter(1)
f()
代码语言:javascript复制1
闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域。
代码语言:javascript复制import requests
def outter(url):
def get():
response = requests.get(url)
print(f'done:{url}')
return get
baidu=outter('https:www.baidu.com')
baidu()
代码语言:javascript复制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}")
代码语言:javascript复制welcome egon to home page
<function home at 0x102977620> time is -1.0005171298980713
res: egon
装饰器模板
代码语言:javascript复制def deco(func):
def wrapper(*args,**kwargs)
res = func(*args,**kwargs)
return res
return wrapper
无参装饰器
代码语言:javascript复制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()
有参装饰器
代码语言:javascript复制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')
注意:装饰器给函数增加功能吗,但是不改变函数内部的语法,不改变函数调用方式