一:编写函数,(函数执行的时间是随机的)
import time def timmer(func): def wrapper(*args,**kwargs): start= time.time() func(*args,**kwargs) stop = time.time() print('执行时间是%s'%(stop-start)) return wrapper @timmer def exe(): print('装饰器练习题!') exe()
二:编写装饰器,为函数加上统计时间的功能
import time
def timmer(func):
def wrapper(*args,**kwargs):
start= time.time()
func(*args,**kwargs)
stop = time.time()
print('执行时间是%s'%(stop-start))
return wrapper
@timmer
def exe():
print('钟意你!')
exe()
三:编写装饰器,为函数加上认证的功能
def auth(func): def wrapper(*args,**kwargs): name = input('请输入你的名字>>: ').strip() password = input('请输入你的密码>>: ').strip() if name == 'sean' and password == '111': func(*args,**kwargs) return wrapper @auth def my_log(name): print('%s欢迎登陆'%(name)) my_log('sean')
四:编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
注意:从文件中读出字符串形式的字典,可以用eval('{"name":"egon","password":"123"}')转成字典格式
current_user = {'name':None} def auth(func): def wrapper(*args,**kwargs): if current_user['name']: func(*args, **kwargs) else: name = input('请输入你的用户名>>: ').strip() password = input('请输入你的密码>>: ').strip() with open('登录文件.txt','r',encoding = 'utf-8') as f: line = f.readline() my_dic = eval(line) if name == my_dic['name'] and password == my_dic['password']: func(*args,**kwargs) current_user['name'] = name else: print('your input not exists') return wrapper @auth def my_log(): print('this is my_log') @auth def my_name(): print('欢迎登陆') my_log() my_name()
五:编写装饰器,为多个函数加上认证功能,要求登录成功一次,在超时时间内无需重复登录,超过了超时时间,则必须重新登录
import time,random user={'user':None,'login_time':None,'timeout':0.000003,} def timmer(func): def wrapper(*args,**kwargs): s1=time.time() res=func(*args,**kwargs) s2=time.time() print('%s' %(s2-s1)) return res return wrapper def auth(func): def wrapper(*args,**kwargs): if user['user']: timeout=time.time()-user['login_time'] if timeout < user['timeout']: return func(*args,**kwargs) name=input('name>>: ').strip() password=input('password>>: ').strip() if name == 'sean' and password == '11': user['user']=name user['login_time']=time.time() res=func(*args,**kwargs) return res return wrapper @auth def index(): time.sleep(random.randrange(3)) print('welcome to index') @auth def home(name): time.sleep(random.randrange(3)) print('welcome %s to home ' %name) index() home('sean')
六:编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
def objt(): url = input('请输入URL路径:') from urllib.request import urlopen ret = urlopen(url).read() return ret ret = objt() ret = ret.decode('utf-8') import os with open('aa.html', 'w', encoding='utf-8') as html: html.write(ret)
七:为题目六编写装饰器,实现缓存网页内容的功能:
具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后存到文件中
扩展功能:用户可以选择缓存介质/缓存引擎,针对不同的url,缓存到不同的文件中
from urllib.request import urlopen import os def cache(func): def inner(*args, **kwargs): if os.path.getsize("web_html"): # 判断文件大小调用OS模块 with open("web_html", "rb") as f: return f.read() # 如果文件不为空,则直接返回 ret = func(*args, **kwargs) with open("web_html", "wb") as f: f.write(b"***" + ret) return ret return inner @cache def get_url(url): code = urlopen(url).read() return code
八:还记得我们用函数对象的概念,制作一个函数字典的操作吗,来来来,我们有更高大上的做法,在文件开头声明一个空字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作
dic = {} def make(ch): def wrap(func): def inner(): dic[ch] = func return inner return wrap @make('select') def select(): print("select!!") @make('update') def update(): print("update!!") select() update() print(dic)
九 编写日志装饰器,实现功能如:一旦函数f1执行,则将消息2017-07-21 11:12:11 f1 run写入到日志文件中,日志文件路径可以指定
注意:时间格式的获取
import time,os def auth(logfile): def deco(func): if not os.path.exists(logfile): with open(logfile,'w',encoding = 'utf-8') as f: pass def wrapper(*args,**kwargs): res = func(*args,**kwargs) with open(logfile,'a',encoding = 'utf-8') as f: f.write('%s %s run'%(time.strftime('%Y-%m-%d %X'),func.__name__)) return wrapper return deco @auth('suhao.txt') def index(): print('this is my index') index()