python 2.07 装饰器进阶试题
装饰器进阶 测试
作业
-
请为以下所有函数编写一个装饰器,添加上装饰器后可以实现:执行func时,先执行func函数内部代码,再输出 "after"
def func(a1): return a1 + "傻叉" def base(a1,a2): return a1 + a2 + '傻缺' def foo(a1,a2,a3,a4): return a1 + a2 + a3 + a4 + '傻蛋' # import functools def outer(funcs): functools.wraps(funcs) def wrapper(*xargs,**kwargs): res = funcs(*xargs,**kwargs) print('after') return res return wrapper @outer def func(a1): return a1 + "傻叉" print(func("1231")) -
请为以下所有函数编写一个装饰器,添加上装饰器后可以实现:将被装饰的函数执行5次,讲每次执行函数的结果按照顺序放到列表中,最终返回列表。
import random import functools # 请为以下所有函数编写一个装饰器,添加上装饰器后可以实现:将被装饰的函数执行5次,讲每次执行函数的结果按照顺序放到列表中,最终返回列表。 def outer(funcs): functools.wraps(funcs) def wrapper(*xargs,**kwargs): res_list = [] for i in range(5): res = funcs(*xargs,**kwargs) res_list.append(res) return res_list return wrapper @outer def func(): return random.randint(1,4) result = func() # 内部自动执行5次,并将每次执行的结果追加到列表最终返回给result print(result) 第二 生成式 def outer(funcs): functools.wraps(funcs) def wrapper(*xargs,**kwargs): return [funcs(*xargs,**kwargs) for i in range(5) ] return wrapper @outer def func(): return random.randint(1,4) result = func() # 内部自动执行5次,并将每次执行的结果追加到列表最终返回给result print(result) -
请为以下函数编写一个装饰器,添加上装饰器后可以实现: 检查文件所在路径(文件件)是否存在,如果不存在自动创建文件夹(保证写入文件不报错)。
def write_user_info(path): file_obj = open(path, mode='w', encoding='utf-8') file_obj.write("武沛齐") file_obj.close() write_user_info('/usr/bin/xxx/xxx.png') ######### # 请为以下函数编写一个装饰器,添加上装饰器后可以实现: 检查文件所在路径(文件件)是否存在,如果不存在自动创建文件夹(保证写入文件不报错)。 import functools import os.path def outter(func): functools.wraps(func) def wrapper(*xargs, **kwargs): if not os.path.exists(os.path.dirname(*xargs)): os.makedirs(os.path.dirname(*xargs)) res = func(*xargs, **kwargs) return res return wrapper @outter def write_user_info(path): file_obj = open(path, mode='w', encoding='utf-8') file_obj.write("123231") file_obj.close() write_user_info(r'C:\Python001\day01\filaaaaa\123.txt') -
分析代码写结果:
def get_data(): scores = [] def inner(val): scores.append(val) print(scores) return inner func = get_data() func(10) func(20) func(30) # 10 10,20 10,20,30 -
看代码写结果
name = "武沛齐" def foo(): print(name) def func(): name = "root" foo() func() # root -
看代码写结果
name = "武沛齐" def func(): name = "root" def foo(): print(name) foo() func() #root -
看代码写结果
def func(val): def inner(a1, a2): return a1 + a2 + val return inner func(val) = a1 +a2 +val data_list = [] for i in range(10): data_list.append( func(i) ) print(data_list) 列表里面是func(0,1,..9),又因为func函数的返回值是inner函数。所以 列表的元素是inner函数。 [inner函数,inner函数,inner函数,inner函数,] -
看代码写结果
def func(val): def inner(a1, a2): return a1 + a2 + val return inner data_list = [] for i in range(10): data_list.append(func(i)) # append 插入是顺序插入 0.。。9 v1 = data_list[0](11,22) v2 = data_list[2](33,11) print(v1) # 列表的元素加括号代表执行函数,11,22 传参 ,元素的索引值等于i的值, 11 +22 +0 =33 print(v2) 33+11+2=46 -
编写函数(函数执行时间用time.sleep(n)代表)
def index(num):
for i in range(num):
print('run %s'%num)
index(5)
#
def index(num):
time.sleep(num)
print('run %s秒' % num)
index(5)
- 编写装饰器,为函数添加统计时间的功能
import time
from functools import wraps
def outter(func):
@wraps(func)
def wrapper(*xargs,**kwargs):
'help'
start_time= time.time()
res= func(*xargs,**kwargs)
stop_time= time.time()
print('run times is %s S'%(stop_time-start_time))
return res
return wrapper
@outter
def index(num):
for i in range(num):
print('run %s'%num)
time.sleep(3)
index(5)
- 编写装饰器 为函数加上认证的功能
import time
from functools import wraps
def login(func):
def wrapper(*xargs,**kwargs):
imp_name = input('type you name: ').strip('')
imp_paswwd = input('type you password: ').strip('')
if imp_name == '123' and imp_paswwd =='123':
print('welcome,loging sucess')
res= func(*xargs,**kwargs)
return res
else:
print('name or password error')
return wrapper
def outter(func):
@wraps(func)
def wrapper(*xargs,**kwargs):
'help'
start_time= time.time()
res= func(*xargs,**kwargs)
stop_time= time.time()
print('run times is %s S'%(stop_time-start_time))
return res
return wrapper
@login
@outter
def index(num):
for i in range(num):
print('run %s'%num)
time.sleep(3)
index(5)
- 编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,
后续的函数都无需再输入用户和密码。
注意从文件中读出字符串形式的字典,可以用eval({'name':'zhangshan','password':'123'})转成字典格式
# 思路 1、把文件中用户名和密码传到字典中去
# 2、登录函数 把输入的用户名和密码和 字典中的用户和密码 进行对比
# 3、登录函数内 把对比后的结果传回全局变量中去。
# 4、登录装饰器 把装饰器函数加到其他函数头部
# 5、在登录装饰器内部,校验全局变量是否有用户登录状态,如果有则调用原始函数
# 6、如果状态是空,调用登录函数
import time
with open('db.txt','r',encoding='utf-8') as f:
user_dict = eval(f.read())
log_user = {'name':None}
# 全局变量分为可变类型和不可变类型 (变量的值更改后,值所在的内存地址会不会变,不会变成为可变类型,会变称为不可变类型)
# globals 定义全局变量在函数内修改,如果是可变类型不需要加globals 不可变类型的话就需要加声明
def login():
while True:
imp_name = input('type name :').strip('')
imp_password = input('type password :').strip('')
if imp_name == user_dict['name'] and imp_password == user_dict['password']:
print('loging ssuccessful!')
log_user['name'] = imp_name
# print(log_user.get('name'))
break
else:
print('user or pass error')
def outter(func):
def wrapper(*xargs,**kwargs):
if log_user['name']:
res = func(*xargs,**kwargs)
return res
else:
login()
return wrapper
@outter
def index1(x):
for i in range(x):
print('index1')
@outter
def index2(x):
for i in range(x):
print('index2')
@outter
def index3(x):
for i in range(x):
print('index3')
index1(1)
time.sleep(2)
index2(1)
index3(1)
- 编写装饰器,为多个函数添加上认证功能,要求登录成功一次,在超时时间是5秒 ,无需重复登录。超过了超时时间,则必须重新登录
import time
with open('db.txt','r',encoding='utf-8') as f:
user_dict = eval(f.read())
login_user = {'name':None}
def login():
while True:
imp_name = input('type name :').strip('')
imp_password = input('type password :').strip('')
if imp_name == user_dict['name'] and imp_password == user_dict['password']:
print('loging ssuccessful!')
old_time= time.time()
global login_user
login_user['name']=[imp_name,imp_password,old_time]
break
else:
print('user or pass error')
def outter(func):
def wrapper(*xargs,**kwargs):
if login_user['name']:
new_time = time.time()
if (new_time-login_user['name'][2]) <= 5:
res = func(*xargs,**kwargs)
return res
else:
login()
else:
login()
return wrapper
@outter
def index1(x):
for i in range(x):
print('index1')
@outter
def index2(x):
print('index2')
index1(1)
time.sleep(6)
index2(1)
总结 4、5 两题 在第一个函数的认证功能执行成功后,应该去执行当前装饰的函数,不应该跳过,
超时时间过了,再去执行函数时,应该重新认证后,再去执行函数
# 更新版本
import time
with open('db.txt', 'r', encoding='utf-8') as f:
user_dict = eval(f.read())
login_user = {'name': None}
def login():
while True:
imp_name = input('type name :').strip('')
imp_password = input('type password :').strip('')
if imp_name == user_dict['name'] and imp_password == user_dict['password']:
print('loging ssuccessful!')
old_time = time.time()
global login_user
login_user['name'] = [imp_name, imp_password, old_time]
break
else:
print('user or pass error')
def outter(func):
def wrapper(*xargs, **kwargs):
if login_user['name']:
new_time = time.time()
if (new_time - login_user['name'][2]) <= 5:
res = func(*xargs, **kwargs)
return res
else:
login()
res = func(*xargs, **kwargs)
return res
else:
login()
res = func(*xargs, **kwargs)
return res
return wrapper
@outter
def index1(x):
for i in range(x):
print('index1')
@outter
def index2(x):
print('index2')
index1(1)
time.sleep(6)
index2(1)
- ATM项目中使用 函数对象 + 字典的方式做了一个格式化的输出
现在需要在文件开头声明一个空的字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作
第一种方式
func_dict= {}
x= 0
def outter(func):
global x
func_dict[x]=func
x += 1
def wrapper(*xargs,**kwargs):
res = func(*xargs,**kwargs)
return res
return wrapper
@outter
def index1():pass
@outter
def index2():pass
@outter
def index3():pass
@outter
def index4():pass
@outter
def index5():pass
print(func_dict)
第二种方式
func_dict = {}
def outter(func):
func_dict[func.__name__]=func
def wrapper(*xargs, **kwargs):
res = func(*xargs, **kwargs)
return res
return wrapper
@outter
def index1(): pass
@outter
def index2(): pass
@outter
def index3(): pass
@outter
def index4(): pass
@outter
def index5(): pass
for i in func_dict:
print('%s %s '%(i,func_dict[i]))
- 编写日志装饰器,实现功能: 一旦执行函数f1 ,则消息 20xx-xx-xx 00:00:00 f1 run 写到日志文件中去
import time
time_date = time.strftime('%Y-%m-%d %X')
def outter(func):
def wrapper(*xargs,**kwargs):
res = func(*xargs,**kwargs)
with open('log.txt','a',encoding='utf-8') as f:
f.write('%s %s run \n'%(time_date,func.__name__))
return res
return wrapper
@outter
def log():
print('log .......')
log()
浙公网安备 33010602011771号