zoukankan      html  css  js  c++  java
  • 关于装饰器的两个小练习

    关于装饰器的小练习

    第一题

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

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

    代码如下:

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

  • 相关阅读:
    JavaScript--Promise(1)
    JavaScript--创建对象
    JavaScript--JSON
    JavaScript--generator
    JavaScript--闭包(1)
    JavaScript--sort()
    JavaScript--filter()
    JavaScript--map()&reduce()
    JavaScript--map&set
    3.11
  • 原文地址:https://www.cnblogs.com/ChinacloudTech/p/9918171.html
Copyright © 2011-2022 走看看