關於裝飾器的小練習
關於裝飾器的小練習
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;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("\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函式,獲得檔案的大小。其他沒有什麼。