关于装饰器的两个小练习

关于装饰器的小练习

第一题

最近刚学了装饰器,最近有个小练习,自己实现了下,具体需求如下:

编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码

代码如下:

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函数,获得文件的大小。其他没有什么。

posted @ 2018-11-06 21:15  行者马  阅读(324)  评论(0编辑  收藏  举报