关于装饰器的两个小练习
python 装饰器练习题
第一题
最近刚学了装饰器,最近有个小练习,自己实现了下,具体需求如下:
编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
代码如下:
goods_number=0 Flag=False def getUseNameandpassword(userdict) : with open("Customer.txt",mode="r",encoding="UTF-8") as f : for line in f : #print(line) strusers=line.split(";") #print(strusers) if strusers==[] : print("no user") else : userdict[strusers[0]]= strusers[1].strip("\n") #print(userdict) return userdict def Login(func) : def inner(*args,**kwargs) : global Flag userdict = {} getUseNameandpassword(userdict) if Flag : ret = func(*args, **kwargs) return ret else : strname = input("请输入你的名字:") strpassword = input("请输入你的密码:") if strname in userdict.keys() and strpassword == userdict[strname] : print("登录成功!") Flag=True ret = func(*args, **kwargs) return ret else : print("登录失败") return inner @Login def Stroe_add() : global goods_number goods_number+=1 print("添加一个商品,商品的数量是:%d" %(goods_number)) return goods_number @Login def Stroe_del() : global goods_number goods_number -= 1 print("删除一个商品商品,商品还剩:%d" %(goods_number)) return goods_number Stroe_add() Stroe_del()
输出结果如下:
请输入你的名字:liudehua
请输入你的密码:896
登录失败
请输入你的名字:anwei
请输入你的密码:349
登录成功!
删除一个商品商品,商品还剩:-1
请输入你的名字:Cosmo
请输入你的密码:456
登录成功!
添加一个商品,商品的数量是:1
删除一个商品商品,商品还剩:0
这里用到一个文件Customer.txt(每行包含一个用户名和密码,用户名和密码用;分开),文件的内容如下:
jianchao;123Cosmo;456pengkun;789anwei;349lixiaolong;786
总结:
这么一个小的联系,写了将近一个小时,遇到很多以前不是非常熟悉的知识。如下:
1 for 循环读取文件的时候不太清楚line存储的是什么导致还用readline去读。
for line in f : #print(line) strusers=line.split(";") #print(strusers) if strusers==[] : print("no user") else : userdict[strusers[0]]= strusers[1].strip("\n")
2 split方法不知道具体用法
Syntax
string.split(separator, max)
Parameter Values
separator 可选参数,指定分隔字符串时要使用的分隔符。默认值是空白
max 可选参数,指定要执行多少次分割。默认值为-1,即“所有事件”.
3 global Flag的用法,不加会报错
4 有些很不完美的地方,比如对一些异常的处理,全局变量的使用,还用goods_number不能为负数的问题。
第二题
1.编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
2.为题目1编写装饰器,实现缓存网页内容的功能:
具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后存到文件中
import os from urllib.request import urlopen def cache(func): def inner(*args,**kwargs): if os.path.getsize('web_cache'): with open('web_cache','rb') as f: return f.read() ret = func(*args,**kwargs)#get() with open('web_cache','wb') as f: f.write(b'*********'+ret) return ret return inner @cache def get(url): code = urlopen(url).read() return code # {'网址':"文件名"} ret = get('http://www.baidu.com') print(ret) ret = get('http://www.baidu.com') print(ret) ret = get('http://www.baidu.com') print(ret)
结果如下:
这里重要用到了一个os模块中的os.path.getsize函数,获得文件的大小。其他没有什么。