Day 12 闭包函数/装饰器
闭包函数
闭包函数:将函数和变量包起来
def make_averager():
series = []
def averager(new_value):
series.append(new_value)
total = sum(series)
return total/len(series)
return averager
avg = make_averager()
print(avg(10))
print(avg(20))
print(avg(30))
10.0
15.0
30.0
装饰器
装饰器也是一个函数
两大原则:
- 不改变被装饰函数的源代码
- 不改变被装饰函数的调用
def deco(func):
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
print("I'm Tiny")
return res
return wrapper
@deco
def say(x):
print(f'Hello,{x}')
return 'Nice to meet you'
say = say('nick')
print(say)
上述的装饰器,最后调用say()的时候,其实是在调用wrapper(),如果say()有返回值,那么wrapper()内也需要返回这个值,即上述的res
如果say()需要传入参数,那么wrapper()内也要传入相同的参数,但是因为我们不知道say()中传入什么参数,所有可以使用*args,**kwargs万能参数来表示
python装饰器语法糖
在被装饰函数正上方,并且是单独一行写上@装饰器名
就可以直接调用被装饰函数
三层装饰器
import time
current_uesr = {'username': None}
def auth(engine='file'):
def login(func):
# func = 最原始的index
def wrapper(*args, **kwargs):
if current_user['username']:
res = func(*args, **kwargs)
return res
user = input('username: ').strip()
pwd = input('password: ').strip()
if engine == 'file':
print('base of file')
if user == 'nick' and pwd == '123':
print('login successful')
current_uesr['usre'] = user
res = func(*args, **kwargs)
return res
else:
print('user or password error')
elif engine == 'mysql':
print('base of mysql, please base of file')
elif engine == 'mongodb':
print('base of mongodb, please base of file')
else:
print('please base of file')
return wrapper
return login
@auth(engine='mysql')
def home(name):
print(f"welcome {name} to home page")
time.sleep(1)
@auth(engine='file')
def index():
print('welcome to index')
time.sleep(1)
res = index()
username: nick
password: 123
base of file
login successful
welcome to index