关于装饰器的小练习
第一题
最近刚学了装饰器,最近有个小练习,自己实现了下,具体需求如下:
编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
代码如下:
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("
")
#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;123
Cosmo;456
pengkun;789
anwei;349
lixiaolong;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("
")
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函数,获得文件的大小。其他没有什么。