函数装饰器练习题
1.文件a.txt内容:每一行内容分别为商品名字,价钱,个数。 apple 10 3 tesla 100000 1 mac 3000 2 lenovo 30000 3 chicken 10 3 通过代码,将其构建成这种数据类型:[{'name':'apple','price':10,'amount':3},{'name':'tesla','price':1000000,'amount':1}......] 并计算出总价钱。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
dic = {} lis = [] price = 0 with open('a.txt',encoding='utf-8') as f_read: for f in f_read.readlines(): content = f.split('\n') dic['name'] = content[0].split()[0] dic['price'] = content[0].split()[1] dic['amount'] = content[0].split()[2] price += int(dic['price']) * int(dic['amount']) lis.append(dic) print(lis) print(price)
2.有如下文件:
------------------------------------------------------------ alex是老男孩python发起人,创建人。 alex其实是人妖。 谁说alex是sb? 你们真逗,alex再牛逼,也掩饰不住资深屌丝的气质。 ------------------------------------------------------------ 将文件中所有的alex都替换成大写的SB。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import os with open('d.txt',encoding='utf-8') as f_read, \ open('.d.txt.swap','w',encoding='utf-8') as f_write: f = f_read.read() f_write.write(f.replace('alex','SB')) os.remove('d.txt') os.rename('.d.txt.swap','d.txt')
3.文件a1.txt内容:每一行内容分别为商品名字,价钱,个数。 文件内容: name:apple price:10 amount:3 year:2012 name:tesla price:100000 amount:1 year:2013 通过代码,将其构建成这种数据类型: [{'name':'apple','price':10,'amount':3}, {'name':'tesla','price':1000000,'amount':1}......] 并计算出总价钱。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
lis = [] dic = {} price = 0 with open('d.txt',encoding='utf-8') as f_read: for f in f_read.readlines(): content = f.split('\n')[0].split() for j in content: dic[j.split(':')[0]] = j.split(':')[1] price += int(dic['price']) * int(dic['amount']) lis.append(dic) print(lis) print(price)
4.文件内容: 序号 部门 人数 平均年龄 备注 1 python 30 26 单身狗 2 Linux 26 30 没对象 3 运营部 20 24 女生多 通过代码,将其构建成这种数据类型: [{'序号':'1','部门':Python,'人数':30,'平均年龄':26,'备注':'单身狗'}, ......]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
lis = [] dic = {} key_list = [] value_list = [] with open('a.txt',encoding='utf-8') as f_read: f1 = f_read.readline().split('\n')[0].split(' ') for k in f1: if not len(k): continue key_list.append(k) for v in f_read.readlines(): v = v.split('\n')[0].split(' ') for r_v in v: if not len(r_v): continue value_list.append(r_v) for long in range(len(key_list)): dic[key_list[long]] = value_list[long] lis.append(dic) print(lis) ret = [] with open('a.txt',encoding='utf-8') as f1: li = f1.readline().split() for i in f1: dic = {} for j in range(len(li)): dic[li[j]] = i.split()[j] ret.append(dic) print(ret) lis = [] with open('a.txt',encoding='utf-8') as f2: keys = [i for i in f2.readline().split()] for value in f2: lis.append({k:v for k,v in zip(keys,value.split())}) print(lis)
5.写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
a = [1,2,3,4] def func1(args): l = [] for i in range(len(args)): if i % 2 == 1: l.append(args[i]) return l print(func1(a)) def func(args):return args[0::2] # 步长切片 print(func(a))
6.写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
a='asdasdasd' b=['asda','','asd'] c=(1,12) def func(args): if len(args) >= 5: return "大于或等于5" return "小于5" print(func(a)) print(func(b)) print(func(c)) def func(args): return "%s 大于或等于5" %str(args) if len(args) >= 5 else "%s 小于5" %str(args) print(func(a)) print(func(b)) print(func(c)) def func1(argv): return len(argv) > 5 # 直接返回bool值
7.写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
a = [1,2,3,4,5] def func(argv): if len(argv)>2: return argv[0:2] return argv def func(argv): return argv[:2] if len(argv) > 2 else argv def func(argv): return argv[0:2] print(func(a))
8.写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数,并返回结果。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def func(argv): n = 0 s = 0 space = 0 o = 0 for i in argv: if i.isdigit(): n+=1 elif i.isalpha(): s += 1 elif i.isspace(): space += 1 else: o += 1 print('数字%s个,字符%s个,空格%s个,其它%s个' %(n,s,space,o)) func('as asd 123<> 123')
9.写函数,检查用户传入的对象(字符串、列表、元组)的每一个元素是否含有空内容,并返回结果。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
a =('1','',2) def func(argv): for i in argv: i = str(i) if i.isdigit(): print(i) continue elif i.isspace(): return argv,"有空值" return argv,'无空值' print(func(a))
10.写函数,检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。 dic = {"k1": "v1v1", "k2": [11,22,33,44]} PS:字典中的value只能是字符串或列表
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
dic = {"k1": "v1v1", "k2": [11,22,33,44]} def func(argv): for k in argv: if len(argv[k]) > 2: argv[k] = argv[k][0:2] return argv print(func(dic)) def func(argv): for k in argv: argv[k] = argv[k][:2] return argv print(func(dic))
11.写函数,接收两个数字参数,返回比较大的那个数字。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def func(x,y): return x if x > y else y print(func(4,6))
12.写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的批量修改操作.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import os def func(f,old,new): with open(f,encoding='utf-8') as f_r,\ open('.%s.bak' %f,'w',encoding='utf-8') as f_w: for i in f_r.readlines(): f_w.write(i.replace(old,new)) os.remove(f) os.rename('.%s.bak' %f,f) func('d.txt','alex','SB')
13.写一个函数完成三次登陆功能,再写一个函数完成注册功能
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def userfile(): username = input("请输入用户名:").strip() password = input("请输入密码:").strip() return username,password def register(): while True: info = userfile() username, password = info[0], info[1] with open('user.txt','r+',encoding='utf-8') as f: for i in f: li = i.strip().split() if username == li[0] or len(username) == 0 : print('用户名已存在,请重新输入') break else: f.write('\n%s %s' %(username,password)) break return "注册成功" def login(): count = 0 while count < 3: count += 1 info = userfile() username, password = info[0], info[1] with open('user.txt',encoding='utf-8') as f: for i in f.readlines(): i = i.split('\n')[0] user,pwd = i.split(' ')[0],i.split(' ')[1] if username == user and password == pwd: return "%s登陆成功" %username else: continue return "登陆失败" def func(): print('welcome to one world one dream') while True: choice = input('请输入你要进行的操作1.登陆 2.注册 3.退出').strip() if not len(choice):continue if int(choice) == 1: ret = login() print(ret) elif int(choice) == 2: ret = register() print(ret) continue else: print("bye") break func()
14.模拟公司hr录入员工账号密码的程序。 1),员工的账号密码存储在这种数据类型中: user_list = [ {'username':'barry','password':'1234'}, {'username':'alex','password':'asdf'}, ......... ] 2)非法字符模板:board = ['张三','李小四','王二麻子'] 3)Hr输入用户名,密码(可持续输入,如果想终止程序,那就在输入用户名时输入Q或者q退出程序), 在Hr输入用户名时,检测此用户名是否有board里面的非法字符,如果有非法字符, 则将非法字符替换成同数量的*(如王二麻子替换成****),然后添加到user_list中, 如果没有非法字符,则直接添加到user_list中,每次添加成功后,打印出刚添加的用户名,密码。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
user_list = [ {'username':'barry','password':'1234'}, {'username':'alex','password':'asdf'}] board = ['张三','李小四','王二麻子'] while True: username = input('请输入用户名:').strip() if not username:continue if username.upper() == 'Q':break if username in board: username = username.replace(username,'*'*len(username)) password = input('请输入密码:').strip() dic = {} dic['username'] = username dic['password'] = password user_list.append(dic) print(dic) print(user_list)
15.按要求完成下列转化(不要按照索引去做)。 list3 = [ {"name": "alex", "hobby": "抽烟"}, {"name": "alex", "hobby": "喝酒"}, {"name": "alex", "hobby": "烫头"}, {"name": "alex", "hobby": "Massage"}, {"name": "wusir", "hobby": "喊麦"}, {"name": "wusir", "hobby": "街舞"}, ] 如何把上面的列表转换成下方的列表? list4 = [ {"name": "alex", "hobby_list": ["抽烟", "喝酒", "烫头", "Massage"]}, {"name": "wusir", "hobby_list": ["喊麦", "街舞"]}, ]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
dic3 = {} dic4 = {} list4 = [] for i in list3: dic3.setdefault('name') dic4.setdefault('name') dic3.setdefault('hobby',[]) dic4.setdefault('hobby',[]) if i['name'] == 'alex': dic3['name'] = 'alex' dic3['hobby'].append(i['hobby']) else: dic4['name'] = 'wusir' dic4['hobby'].append(i['hobby']) list4.append(dic3) list4.append(dic4) print(list4)
16.实现一个整数加法计算器: 如:content = input(‘请输入内容:’) # 如用户输入:5+8+7....(最少输入两个数相加), 然后进行分割再进行计算,将最后的计算结果添加到此字典中(替换None): dic={‘最终计算结果’:None}。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
dic = {} sum = 0 content = input('>>').strip() content = content.split('+') for i in content: i = int(i) sum += i dic['最终计算结果']=sum print(dic)
17.查找列表li中的元素,移除每个元素的空格,并找出以’A’或者’a’开头,并以’c’结尾的所有元素,并添加到一个新列表中,最后循环打印这个新列表
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
li = ['taibai ','alexC','AbC ','egon',' Ritian',' Wusir',' aqc'] n_l = [] for i in li: i = i.strip() # if (i.startswith('a') or i.startswith('A')) and i.endswith('c'): if i.upper().startswith('A') and i.endswith('c'): n_l.append(i) print(n_l)
18.补充代码(从已有的代码下面继续写): 有如下值li= [11,22,33,44,55,77,88,99,90],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
li = [11,22,33,44,55,77,88,99,90] result = {} for row in li: result.setdefault('k1',[]) result.setdefault('k2',[]) if row > 66: result['k1'].append(row) else: result['k2'].append(row) print(result)
19.计算用户输入内容中索引为奇数并且对应的元素为数字的个数(没有则个数为零)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
count = 0 content = input('>>').strip() for k,v in enumerate(content): print(k,v,type(v),v.isdigit()) if k % 2 == 1 and v.isdigit(): count += 1 print(count) a = '2' print(a.isdigit())
20.分别使用while循环,和for循环打印1-2+3-4+5.......+99的结果
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
sum = 0 n=1 while n < 100: if n % 2 == 0: sum -= n else: sum += n n += 1 print(sum) sum = 0 for i in range(100): if i % 2 == 0: sum -= i else: sum += i print(sum) for i in range(100,-1,-1): print(i)
21.有列表li = [‘alex’,’wusir’,’rain’],通过操作该列表构造一个字符串s=’alexwusirrain
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
li = ['alex','wusir','rain'] s= li[0]+li[1]+li[2] print(s) s1 = '*'.join(li) print(s1) print(s.split('l',1))
22.写函数,返回一个扑克牌列表,里面有52项,每一项是一个元组 例如:[(‘红心’,2), (‘草花’,2), …(‘黑桃,‘A’)]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def puke(): num = [] for n in range(2,11): num.append(n) num.extend(['J','Q','K','A']) lis = [] base = ['红心','草花','黑桃','方块'] for item in base: for m in num: lis.append((item,m)) return lis print(puke())
23.写函数,传入n个数,返回字典{‘max’:最大值,’min’:最小值} 例如:min_max(2,5,7,8,4) 返回:{‘max’:8,’min’:2}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def min_max(*args): l = [] dic ={} for i in args: l.append(i) l.sort() dic['max'] = l[-1] dic['min'] = l[0] return dic print(min_max(2,5,7,8,4)) def min_max(*args): the_max = args[0] the_min = args[0] for i in args: if i > the_max: the_max = i elif i < the_min: the_min = i return {'max':the_max,'min':the_min} print(min_max(2,5,7,8,4))
24.写函数,专门计算图形的面积 其中嵌套函数,计算圆的面积,正方形的面积和长方形的面积 调用函数area(‘圆形’,圆半径) 返回圆的面积 调用函数area(‘正方形’,边长) 返回正方形的面积 调用函数area(‘长方形’,长,宽) 返回长方形的面积
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import math def area(name,*args): def round(x): return math.pi * x ** 2 def square(x): return x ** 2 def rectangle(x,y): return x * y if name == '圆形': return round(*args) elif name == '正方形': return square(*args) elif name == '长方形': return rectangle(*args) print(area('圆形',3)) print(area('正方形',3)) print(area('长方形',2,3))
25.写函数,传入一个参数n,返回n的阶乘。例如: cal(7) 计算7 * 6 * 5 * 4 * 3 * 2 * 1
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def cal(n): sum = 1 print(sum) for i in range(n,1,-1): sum = sum * i return sum print(cal(6)) sum = 1 def cal(n): global sum if n >= 1: sum = n * cal(n-1) return sum print(cal(6))
26.编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from urllib import request def func(url): with request.urlopen(url) as f: data = f.read() print('status',f.status,f.reason) for k,v in f.getheaders(): print('%s:%s' %(k,v)) print('Data:',data.decode('utf-8')) func('https://www.baidu.com') import requests def my_down(url = 'https://www.baidu.com'): return requests.get(url).content def get(): return requests.get(url).content return get print(my_down())
27.实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后存到文件中 扩展功能:用户可以选择缓存介质/缓存引擎,针对不同的url,缓存到不同的文件中
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import requests import os def make_cache(func): def inner(*args,**kwargs): if not os.path.exists('cache.txt'): with open('cache.txt','w'): pass if os.path.getsize('cache.txt'): print(os.path.getsize('cache.txt')) with open('cache.txt',encoding='utf-8') as f_read: res = f_read.read() else: print('err') print(os.path.getsize('cache.txt')) res = func(*args,**kwargs) with open('cache.txt','w',encoding='utf-8') as f_write: f_write.write(res.decode('utf-8')) return res return inner @make_cache def get(url): return requests.get(url).content print(get('https://www.baidu.com'))
28.给每个函数写一个记录日志的功能, 功能要求:每一次调用函数之前,要将函数名称,时间节点记录到log的日志中。 所需模块: import time struct_time = time.localtime() print(time.strftime("%Y-%m-%d %H:%M:%S",struct_time))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import time,os def timmer(func): struct_time = time.localtime() def inner(*args): if not os.path.exists('log.txt'): with open('log.txt','w') : pass current_time = time.strftime('%Y-%m-%d %H:%M:%S',struct_time) with open('log.txt','a',encoding='utf-8') as f: f.write("\n%s\t%s"%(current_time,func.__name__)) func() return inner @timmer def test(): print('hello world')
29.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
dic = { 'status' : False } flag = False def auth(func): def inner(*args,**kwargs): user = [] global flag while not flag: user_info = login() with open('user.txt','r+',encoding='utf-8') as f: for i in f: i = i.strip().split() user.append(i[0]) if i[0] == user_info[0] and i[1] == user_info[1]: print('%s login success' %user_info[0]) flag = True if user_info[0] not in user: f.seek(0,2) f.write('\n%s\t%s' %(user_info[0],user_info[1])) flag = True while flag: ret = func(*args,**kwargs) return ret dic['status'] = True return inner def login(): username = input('请输入用户名:').strip() password = input('请输入密码').strip() return username,password @auth def func(): if dic['status']: print(' hello world ') @auth def func1(): if dic['status']: print(' hello elk ') func() func1()
30.在编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码。这个作业之上进行升级操作: 设置两套密码,一套为京东账号密码,一套为淘宝账号密码保存在文件中。 设置四个函数,分别代表 京东首页,京东超市,淘宝首页,淘宝超市。 循环打印四个选项:东首页,京东超市,淘宝首页,淘宝超市。 供用户选择,用户输入选项后,执行该函数,四个函数都加上认证功能,只要登陆成功一次,在选择其他函数,后续都无需输入用户名和密码。 相关提示:用带参数的装饰器。装饰器内部加入判断,验证不同的账户密码。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import os dic = { 'name': None, 'status' : False } def auth(func): def inner(*args,**kwargs): if not dic['status']: username = input('请输入用户名:').strip() password = input('请输入密码:').strip() if not os.path.exists('user.txt'): with open('user.txt','w'):pass with open('user.txt',encoding='utf-8') as f: for i in f: i = i.strip().split() if username == i[0] and password == i[1]: ret = func(*args,**kwargs) dic['name'] = username dic['status'] = True return ret else: ret = func(*args,**kwargs) return ret return inner @auth def func1(): print('京东首页') @auth def func2(): print('京东商城') @auth def func3(): print('淘宝首页') @auth def func4(): print('淘宝商城') while True: func1() func2() func3() func4()
31.写程序完成下列功能: 1),启动程序,首页面应该显示成如下格式: 欢迎来到博客园首页 1:请登录 2:请注册 3:文章页面 4:日记页面 5:评论页面 6:收藏页面 7:注销 8:退出程序 2),用户输入选项,3~6选项必须在用户登录成功之后,才能访问成功。 3),用户选择登录,用户名密码从register文件中读取验证,三次机会,没成功则结束整个程 序运行,成功之后,可以选择访问3~6项,访问页面之前, 必须要在log文件中打印日志, 日志格式为-->用户:xx 在xx年xx月xx日 执行了 %s函数,访问页面时,页面内容为:欢 迎xx用户访问评论(文章,日记,收藏)页面 4),如果用户没有注册,则可以选择注册,注册成功之后,可以自动完成登录,然后进入首页选择。 5),注销用户是指注销用户的登录状态,使其在访问任何页面时,必须重新登录。 6),退出程序为结束整个程序运行。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import os import time flag = False dic = { 'username' : None, 'status' : False } def auth(func): def inner(*args,**kwargs): if not os.path.exists('log.txt'): with open('log.txt', 'w', encoding='utf-8'): pass if dic['status']: with open('log.txt', 'a', encoding='utf-8') as f3: f3.write('用户%s 在%s 执行了%s函数 \n' % (dic['username'],time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()), func.__name__)) ret = func(*args,**kwargs) return ret else: i = 0 while i <= 3: username = input('请输入你的用户名:').strip() password = input('请输入你的密码:').strip() with open('user.txt',encoding='utf-8') as f1: for f in f1: f = f.strip().split() if f[0] == username and f[1] == password: dic['username'] = username dic['status'] = True ret = func(*args,**kwargs) with open('log.txt', 'a', encoding='utf-8') as f3: f3.write('用户:%s 时间:%s exec:%s\n' % (dic['username'], time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()), func.__name__)) return ret else: i += 1 print('用户名或者密码错误,剩余输入次数%s' %(3-i)) continue return inner @auth def login(): print('%s登录成功'%dic['username']) def register(): if not os.path.exists('user.txt'): with open('user.txt',encoding='utf-8'):pass global flag while not flag: username = input('请输入需要注册的用户名:').strip() user_list = [] with open('user.txt','r',encoding='utf-8') as f2: for f in f2: f = f.strip().split() user_list.append(f[0]) if username in user_list: print('该用户已存在,请换个用户名') continue password = input('请输入密码:').strip() double_password = input('请再次输入密码:').strip() if password != double_password: print('密码不匹配,请再次输入') continue with open('user.txt','a',encoding='utf-8') as f3: f3.write('\n%s\t%s' %(username,password)) break print('%s注册成功' %username) dic['username'] = username dic['status'] = True @auth def article(): print('欢迎访问文章页面!') @auth def diary(): print('欢迎访问操作日志页面!') with open('log.txt',encoding='utf-8') as f4: for f in f4: print(f) @auth def comment(): print('欢迎访问评论页面!') @auth def collection(): print('欢迎访问收藏页面!') def log_out(): print('%s注销成功!'%dic['username']) dic['username'] = None dic['status'] = False def web_exit(): global flag flag = True print('程序运行结束!') def display_list(): print('欢迎来到博客园首页') lis = ['请登录','请注册','文章页面','日志页面','评论页面','收藏页面','注销','退出程序'] for l in lis: print(lis.index(l)+1,':',l) return len(lis) def web_index(): global flag while not flag: num_max = display_list() choice = input('请输入要进行的操作:').strip() if not choice.isdigit(): continue choice = int(choice) if choice == 0 or choice > num_max: print('输入不合法,请再次输入!') if choice == 1: login() elif choice == 2: register() elif choice == 3: article() elif choice == 4: diary() elif choice == 5: comment() elif choice == 6: collection() elif choice == 7: log_out() elif choice == 8: web_exit() if __name__ == '__main__': web_index()