python作业讲解_python学习笔记 day12 作业讲解

1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件)

要求成功登陆一次,后续的函数都无需输入用户名和密码

flag=1

defwrapper(f):def inner(*args):globalflagwhileflag:

username=input("username>>>")

password=input("password>>>")

with open('info',mode='r',encoding='utf-8') as file:

line=file.readline().split(' ')if username==line[0] and password==line[1]:print("登录成功!")

flag=0 #登陆成功之后后面的函数都无需再输入用户名密码

ret=f(*args)returnretreturninner

@wrapperdeffunc1(a,b):return a+b

@wrapperdeffunc2(a,b,c):return a*b*cprint('func1函数执行结果:',func1(1,2))print('func2函数执行结果:',func2(1,2,3))

运行结果:

版本二(EVa-J):

flag=0defwrapper(f):def inner(*args):globalflagifflag:

ret= f(*args)returnretelse:

username=input(">>>")

password=input(">>>")

with open('info',encoding='utf-8') as file:

line=file.readline().split(' ')if username==line[0] and password==line[1]:print("登录成功")

flag=1ret=f(*args)returnretelse:print("登录失败")returninner

@wrapperdeffunc1(a,b):return a+b

@wrapperdeffunc2(a,b,c):return a*b*cprint(func1(1,2))print(func2(1,2,3))

版本三(在上面基础上完善了一下,登陆失败后可以重新输入用户名密码,进行尝试)

flag=0deflogin(f):def inner(*args):globalflag

logging=1

whilelogging:if flag: #登录成功,下次就不用在输入用户名密码了

ret = f(*args)returnretelse:

username=input("username>>>")

password=input("password>>>")

with open("info",mode='r',encoding='utf-8') as file:

line=file.readline().split(' ')if username==line[0] and password==line[1]:print("登录成功!")

flag=1ret= f(*args)returnretelse:print("登陆失败")if input("continue?(Y or N)>>>").upper()=='N':

logging=0returninner

@logindefadd_shopping(a,b):print(a,b)return "增加商品"@logindefdel_shopping(a,b):print(a,b)return "删除商品"

print(add_shopping(1,2))print(del_shopping(1,2))

2.编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件:

defwrapper(f):def inner(*args):

ret=f(*args)

with open('info1',mode='a+',encoding='utf-8') as file:

name=f.__name__file.write(name)returnretreturninner

@wrapperdeffunc1(a,b):return a+b

@wrapperdeffunc2(c,d,e):return c*d*e

@wrapperdeffunc3(a,b,c,d,e):returna,b,c,d,eprint(func1(1,2))print(func2(1,2,3))print(func3(1,2,3,4,5))

运行结果:

这需要用到一个函数func.__name__ 可以得到func函数的函数名;

3.编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果:

defdownload(url):

code=urlopen(url).read()return code

4.为3编写装饰器,实现缓存网页内容的功能:

from urllib.request importurlopendefcache(f):def inner(*args,**kwargs):

with open('info2',mode='r+',encoding='utf-8') as file:

line=file.readlines()ifline:print("这是原来下载好的内容",line)else:

ret=f(*args,**kwargs)

file.write(str(ret)+'\n')returnretreturninner

@cachedefdownload(url):

code=urlopen(url).read()returncodeprint('这是新的要下载的内容:',download('https://zhidao.baidu.com/question/520009128815601365.html'))

版本二(Eva-J):

from urllib.request importurlopenimportosdefcache(f):def inner(*args,**kwargs):if os.path.getsize('infp3'):

with open('infp3',mode='rb') as file:returnfile.read()else:

ret=f(*args,**kwargs)

with open("infp3",mode='wb') as file:

file.write(b'****'+ret)returnretreturninner

@cachedeffunc(url):

ret=urlopen(url).read()returnretprint(func('http://www.baidu.com'))print(func('http://www.baidu.com'))print(func('http://www.baidu.com'))

只有第一个是从网页中下载的内容读的(因为读的是ret的内容),后面两个因为第一个下载的内容已经写入文件了(前面加了***)所以独到的是***后面一堆~

上面写的有一个问题就是,如果来一个新的网址,因为文件里面已经有内容了,它读的还是原来网址下载的内容,这其实不合理 ,我们可以改成,来一个url 判断这个url有没有被下载过(可以建一个字典来存,url作为键)如果之前下载过,就从文件里面读取(带有***号的是之前已经下载到文件中了,从文件读取的,不是从网页上下载读到的),如果这个url之前 没有出现过就直接打印下载的网页内容:

from urllib.request importurlopenimportos

dict={}

count=0defcache(f):definner(url):globaldictglobalcountif url indict:

with open("infp3",mode='rb') as file:returnfile.readlines()else:

ret=f(url)

with open('infp3',mode='ab') as file:

file.write(b'***'+ret)

dict[url]=count

count+= 1

returnretreturninner

@cachedeffunc(url):

ret=urlopen(url).read()returnretprint(func("https://www.cnblogs.com/xuanxuanlove/p/9568322.html"))print(func("https://www.baidu.com"))print(func("https://www.baidu.com"))print(func("https://www.bilibili.com/"))print(func("https://www.bilibili.com/"))

运行结果:

第三个和第五个应该是从文件里面读的~

相比之前 第一个url 是从网页下载的,其他的url 不管是不是新的网址,都从文件读第一个url的内容,现在新的网址就从网页下载到文件,从网页读,旧的url 就从文件读(带有***)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值