9–1. 文件过滤. 显示一个文件的所有行, 忽略以井号( # )开头的行. 这个字符被用做python , Perl, Tcl, 等大多脚本文件的注释符号.附加题: 处理不是第一个字符开头的注释.
1 filename = input("输入文件名:")
2 with open(filename) as f:
3 for i in f:
4 if i.startswith('#'):
5 continue
6 else:
7 print(i, end='')
9–2. 文件访问. 提示输入数字 N 和文件 F, 然后显示文件 F 的前 N 行.
1 num = int(input("输入数字:"))
2 filename = input("输入文件名:")
3 with open(filename) as f:
4 for i, j in enumerate(f):
5 if i == (num):
6 break
7 else:
8 print(j, end='')
9–3. 文件信息. 提示输入一个文件名, 然后显示这个文本文件的总行数.
1 filename = input('输入文件名:')
2 with open(filename) as f:
3 allline = f.readlines()
4 print(len(allline))
9–4. 文件访问.
写一个逐页显示文本文件的程序. 提示输入一个文件名, 每次显示文本文件的 25 行, 暂停并向用户提示"按任意键继续.", 按键后继续执行.
1 filename = input("输入文件名:")
2 num = 25
3 with open(filename) as f:
4 for i, j in enumerate(f, 1):
5 if i == num:
6 space = input("输入任意字符回车:")
7 num += 25
8 else:
9 print(j, end='')
9-5 考试成绩,改进你的考试成绩问题(练习5-3和6-4),要求能从多个文件中读入考试成绩。文件的数据格式由你自己决定。
1 filename = input("输入文件名:")
2 with open(filename) as f:
3 for i in f:
4 i = i.strip()
5 if int(i) < 60:
6 print("F")
7 elif int(i) < 70:
8 print("D")
9 elif int(i) < 80:
10 print("C")
11 elif int(i) < 90:
12 print("B")
13 elif int(i) <= 100:
14 print("A")
15 else:
16 print("%s不在范围" % i)
9–6. 文件比较. 写一个比较两个文本文件的程序. 如果不同, 给出第一个不同处的行号和列号.
1 def file(filename1, filename2):
2 with open(filename1) as f1:
3 f1alllines = f1.readlines()
4
5 with open(filename2) as f2:
6 f2alllines = f2.readlines()
7
8 minlen1 = min(len(f1alllines), len(f2alllines))
9 for i in range(minlen1):
10 if f1alllines[i] != f2alllines[i]:
11
12 minlen2 = min(len(f1alllines[i]), len(f2alllines))
13 for j in range(minlen2):
14 if f1alllines[i][j] != f2alllines[i][j]:
15 return '不同行号: %s' % (i+1), '不同列号: %s' % (j+1)
16 return '文件相同'
17
18 if __name__ == '__main__':
19 filename1 = input("输入文件名1:")
20 filename2 = input("输入文件名2:")
21 print(file(filename1, filename2))
9–7. 解析文件. Win32 用户: 创建一个用来解析 windows .ini 文件的程序. POSIX 用户:创建一个解析 /etc/serves 文件的程序. 其它平台用户: 写一个解析特定结构的系统配置文件的程序.
1 windows = {}
2 with open(r'C:\Windows\win.ini') as f:
3 # print(f.readlines())
4 for line in f:
5 if line.startswith(';'):
6 continue
7 if line.startswith('['):
8 iterm = []
9 name = line[1: line.rfind(']')]
10 windows.setdefault(name, iterm)
11 continue
12 if '=' in line:
13 windows[name].append(line.strip())
14 print(windows)
9–8. 模块研究. 提取模块的属性资料. 提示用户输入一个模块名(或者从命令行接受输入).然后使用 dir() 和其它内建函数提取模块的属性, 显示它们的名字, 类型, 值.
1 m = input('输入模块名: ')
2 module = __import__(m)
3 ml = dir(module)
4 # print(ml)
5 for i in ml:
6 print('name: ', i)
7 print('type: ', type(getattr(module,i)))
8 print('value: ', getattr(module,i))
9 print('')
进入 Python 标准库所在的目录. 检查每个 .py 文件看是否有__doc__ 字符串, 如果有, 对其格式进行适当的整理归类. 你的程序执行完毕后, 应该会生成一个漂亮的清单. 里边列出哪些模块有文档字符串, 以及文档字符串的内容. 清单最后附上那些没有文档字符串模块的名字.附加题: 提取标准库中各模块内全部类(class)和函数的文档.
1 import os
2
3 pymodules = {}
4 path = input("输入路径:")
5 pyfiles = [f for f in os.listdir(os.path.abspath(path)) if f.endswith('.py')]
6
7 for f in pyfiles:
8 module = f[:-3]
9 pymodules.setdefault(module, '')
10 pyfile = os.path.join(path, f)
11 file = open(pyfile)
12 doc = False
13 for line in file:
14 if line.strip().startswith('"""') and line.strip().endswith('"""'):
15 pymodules[module] += line
16 file.close()
17 break
18 elif line.strip().startswith('"""') or line.strip().startswith('r"""') and len(line) > 3:
19 doc = True
20 pymodules[module] += line
21 continue
22 elif doc:
23 if line == '"""':
24 pymodules[module] += line
25 file.close()
26 doc = False
27 break
28 else:
29 pymodules[module] += line
30 else:
31 continue
32 file.close()
33
34 hasdoc = []
35 nodoc = []
36 for module in pymodules:
37 if pymodules[module]:
38 hasdoc.append(module)
39 else:
40 nodoc.append(module)
41
42 print('没有文档模块:')
43 for key in nodoc:
44 print(key)
45
46 print("")
47
48 print("有文档模块:")
49 for key in hasdoc:
50 print("%s:%s" % key, pymodules[key])
9-10.家庭理财。创建一个家庭理财程序。你的程序需要处理储蓄 、支票、金融市场 ,定期存款等多
种账户。为每种账户提供一个菜单操作界面 ,要有存款、取款、借、贷等操作 。另外还要提 一个取消操作选项 。用户退出这个程序时相关数据应该保存到文件里去 (出于备份的目的, 序执行过程中也要备份)。
1 # 函数思路不够用,只好用上类
2 import os
3 import JSON
4 import sys
5
6 class Fm:
7
8 def deposit(self):
9 """存款"""
10 money = input("存款:")
11 if money == 'q':
12 self.saving()
13 else:
14 self.user_dict['余额'] += float(money)
15 with open('%s.json' % self.ID, 'w') as f:
16 json.dump(self.user_dict, f)
17 print("存款成功")
18 self.saving()
19
20 def withdrawal(self):
21 """取款"""
22 while True:
23 money = input("取款:")
24 if money == 'q':
25 self.saving()
26 else:
27 if float(money) <= self.user_dict['余额']:
28 self.user_dict['余额'] -= float(money)
29 with open('%s.json' % self.ID, 'w') as f:
30 json.dump(self.user_dict, f)
31 print("取款成功")
32 self.saving()
33 else:
34 print("取款金额超出余额,重新输入")
35
36 def loan(self):
37 """借款"""
38 money = input("存款:")
39 if money == 'q':
40 self.saving()
41 else:
42 self.user_dict['借款'] += float(money)
43 with open('%s.json' % self.ID, 'w') as f:
44 json.dump(self.user_dict, f)
45 print("借款成功")
46 self.saving()
47
48 def credit(self):
49 """贷款"""
50 money = input("贷款:")
51 if money == 'q':
52 self.saving()
53 else:
54 self.user_dict['贷款'] += float(money)
55 with open('%s.json' % self.ID, 'w') as f:
56 json.dump(self.user_dict, f)
57 print("贷款成功")
58 self.saving()
59
60 def saving(self):
61 """储蓄主菜单"""
62 showmenu = ("""
63 [1]存款
64 [2]取款
65 [3]借款
66 [4]贷款
67 [5]返回
68 [6]退出
69
70 请输入编号:""")
71 num = input(showmenu)
72 if num == '6':
73 sys.exit()
74 elif num in '12345':
75 if num == '1': self.deposit()
76 if num == '2': self.withdrawal()
77 if num == '3': self.loan()
78 if num == '4': self.credit()
79 if num == '5': self.main()
80 else:
81 print("输入有误")
82
83 def main(self):
84 """主菜单"""
85 showmenu = ("""
86 [1]储蓄
87 [2]支票(未写)
88 [3]金融市场(未写)
89 [4]定期存款(未写)
90 [5]退出
91
92 请输入编号:""")
93 num = input(showmenu)
94 if num == '5':
95 sys.exit()
96 elif num in '1234':
97 if num == '1': self.saving()
98 else:
99 print("输入有误")
100
101 def reGIStered(self):
102 """注册"""
103 while True:
104 ID = input('ID:')
105 filename = '%s.json' % ID
106 if filename in os.listdir(os.getcwd()):
107 print("用户已存在")
108 else:
109 passwd = input('密码:')
110 name = input('姓名:')
111 registered_user = {}
112 registered_user['密码'] = passwd
113 registered_user['姓名'] = name
114 registered_user['余额'] = 0
115 registered_user['借款'] = 0
116 registered_user['贷款'] = 0
117 filename = open('%s.json' % ID, 'w')
118 json.dump(registered_user, filename)
119 filename.close()
120 print("注册成功")
121 self.user()
122
123 def login(self):
124 """登录"""
125 self.ID = input('ID:')
126 filename = '%s.json' % self.ID
127 if filename in os.listdir(os.getcwd()):
128 with open(filename) as user_file:
129 self.user_dict = json.load(user_file)
130 passwd = input("密码:")
131 if self.user_dict['密码'] == passwd:
132 print("登录成功")
133 print("---------------\n"
134 "姓名:{姓名}\n余额:{余额:.2f}\n借款:{借款:.2f}\n贷款:{贷款:.2f}\n"
135 "---------------".fORMat(**self.user_dict))
136 self.main()
137 else:
138 print("密码错误")
139 else:
140 print("用户不存在")
141
142 def user(self):
143 """账号"""
144 showmenu = ("""
145 [1]注册
146 [2]登录
147 [3]退出
148
149 请输入编号:""")
150 num = input(showmenu)
151 while True:
152 if num == '3':
153 break
154 elif num in '12':
155 if num == '1': self.registered()
156 if num == '2':
157 if self.login():
158 self.main()
159 else:
160 print("输入有误")
161
162 if __name__ == '__main__':
163 fm = Fm()
164 fm.user()
9–11. WEB 站点地址.
a) 编写一个 URL 书签管理程序. 使用基于文本的菜单, 用户可以添加, 修改或者删除书签数据项. 书签数据项中包含站点的名称, URL 地址, 以及一行简单说明(可选). 另外提供检索功能,可以根据检索关键字在站点名称和 URL 两部分查找可能的匹配. 程序退出时把数据保存到一个磁盘文件中去; 再次执行时候加载保存的数据.
b)改进 a) 的解决方案, 把书签输出到一个合法且语法正确的 html 文件(.html 或 htm )中,这样用户就可以使用浏览器查看自己的书签清单. 另外提供创建"文件夹"功能, 对相关的书签进行分组管理.
附加题: 请阅读 Python 的 re 模块了解有关正则表达式的资料, 使用正则表达式对用户输入的 URL 进行验证.
1 import sys
2 import re
3
4 regex = re.compile(r"^(((Http|https)://)" # http、https
5 r"?([a-z]{2,}))\." # www
6 r"([a-z0-9]+)\." #
7 r"([a-z]{3}|([a-z]{3}\.[a-z]{2,4}))$") #com、com.cn
8
9 filename = "bookmark.txt"
10 def add():
11 """添加"""
12 urllist = []
13 while True:
14 url = input("输入地址[b:返回]:").strip()
15 if url == 'b':
16 main()
17 if regex.match(url):
18 urlname = input("输入名称:").strip()
19 description = input("简要说明:").strip()
20 urllist.append(urlname)
21 urllist.append(url)
22 urllist.append(description)
23 with open(filename, 'a+') as f:
24 f.write(str(urllist) + '\n')
25 print('添加成功')
26 else:
27 print("地址不规范")
28
29 def modify():
30 """修改"""
31 urllist = []
32 f = open(filename)
33 for i, j in enumerate(f):
34 urllist.append(eval(j))
35 print(i, j, end='')
36 f.close()
37
38 while True:
39 num = input("修改编号[b:返回]:")
40 if num == 'b':
41 main()
42 if int(num) <= len(urllist):
43 url = input("输入地址:").strip()
44 if regex.match(url):
45 urlname = input("输入名称:").strip()
46 description = input("简要说明:").strip()
47 urllist[int(num)][0] = urlname
48 urllist[int(num)][1] = url
49 urllist[int(num)][2] = description
50 print("修改成功")
51 with open(filename, 'w') as urlfile:
52 for urlline in urllist:
53 urlfile.write(str(urlline) + '\n')
54 else:
55 print("地址不规范")
56 else:
57 print('输入有误')
58
59
60 def delete():
61 """删除"""
62 urllist = []
63 f = open(filename)
64 for i, j in enumerate(f):
65 urllist.append(eval(j))
66 print(i, j, end='')
67 f.close()
68
69 while True:
70 num = input("\n删除编号[b:返回]:")
71 if num == 'b':
72 main()
73 if int(num) <= len(urllist):
74 del urllist[int(num)]
75 print('删除成功')
76 with open(filename, 'w') as urlfile:
77 for urlline in urllist:
78 urlfile.write(str(urlline) + '\n')
79 else:
80 print("输入有误")
81
82 def find():
83 """查找"""
84 urllist = []
85 while True:
86 name = input("查找内容[b:返回]:")
87 if name == 'b':
88 main()
89 with open(filename) as f:
90 for urlline in f:
91 urllist.append(eval(urlline))
92 if name in str(urllist):
93 for urlline in urllist:
94 if name in urlline:
95 print('%s\n名称:%s\n地址:%s\n说明:%s\n%s' %
96 ('-'*20, urlline[0], urlline[1], urlline[2], '-'*20))
97 else:
98 print('书签不存在')
99
100 def main():
101 """主菜单"""
102 showmenu = ("""
103 [1]添加书签
104 [2]修改书签
105 [3]删除书签
106 [4]查找书签
107 [5]退出程序
108
109 请输入编号:""")
110 num = input(showmenu)
111 if num == '5':
112 sys.exit()
113 elif num in '1234':
114 if num == '1': add()
115 if num == '2': modify()
116 if num == '3': delete()
117 if num == '4': find()
118 else:
119 print("输入有误")
120
121 if __name__ == '__main__':
122 main()
9-12 用户名和密码。回顾练习7-5,修改代码使之可以支持“上次登录时间”。请参阅time模块中的文档了解如何记录用户上次登录的时间。另外提供一个系统管理员,他可以导出所有用户的用户名,密码(如需要可以加密),以及上次登录时间。
a)数据应保存在磁盘中,使用冒号:分隔,一次写入一行,例如“Joe:boohoo:953176591.145,文件中数据的行数应该等于你系统上的用户数。
b)进一步改进你的程序,不再一次写入一行,而使用pickle模块保存整个数据对象。请参阅pickle模块的文档了解如何序列化/扁平化对象,以及如何读写保存的对象。一般来说,这个解决方案的代码行数要比a)少;
c)使用shelve模块替换pickle模块,由于可以省去一些维护代码,这个解决方案的代码比b)的更少
1 from datetime import datetime
2 import hashlib, time, sys
3 import pickle as p
4 import shelve as s
5
6 db = {}
7
8 def newuser():
9 """注册"""
10 value = []
11 prompt = 'login desired: '
12 while True:
13 name = input(prompt).lower()
14 if not name.isalnum() and '' in name:
15 print('name format error')
16 continue
17 else:
18 if name in db:
19 prompt = 'name taken, try another: '
20 continue
21 else:
22 break
23 pwd = input('login passWord desired:')
24 m = hashlib.md5()
25 m.update(pwd.encode(encoding='utf-8'))
26 value.append(m.hexdigest())
27 value.append(datetime.now())
28 value.append(time.time())
29 db[name] = value
30 print('new user is %s, register time is %s' % (name, db[name][1]))
31
32 def olduser():
33 """登录"""
34 name = input('Username:').lower()
35 pwd = input('Password:')
36 m = hashlib.md5()
37 m.update(pwd.encode(encoding='utf-8'))
38 passwd = db.get(name)
39 if passwd[0] == m.hexdigest():
40 newtimestamp = time.time()
41 newtime = datetime.now()
42 if newtimestamp - db[name][2] < 14400:
43 print('You already logged in at %s:' % db[name][1])
44 else:
45 passwd[1] = newtime
46 print('Welcome back %s, login time is %s' % (name, passwd[1]))
47 else:
48 print('Login incorrect')
49
50 def removeuser():
51 """删除"""
52 print(db)
53 name = input('Input a user name to remove:').lower()
54 if name in db:
55 db.pop(name)
56 print("Done")
57 else:
58 print('Input error')
59
60 def getuser():
61 """查询"""
62 while True:
63 name = input('login name desired:').lower()
64 if not name.isalnum() and '' in name:
65 print('name format error')
66 continue
67 else:
68 if name not in db:
69 print('User name is not in db')
70 answer = input('register a new user? y/n').lower()
71 if 'y' == answer:
72 newuser()
73 break
74 elif 'n' == answer:
75 break
76 else:
77 print('user name is already in db')
78 olduser()
79 break
80
81 def textfile():
82 """text"""
83 print(db)
84 f = open('account.txt', 'w')
85 f.write(str(db))
86 f.close()
87
88 def picklefile():
89 """pickle"""
90 accountfile = 'pickle.data'
91 f = open(accountfile, 'wb')
92 p.dump(db, f)
93 f.close()
94
95 f = open(accountfile, 'rb')
96 accountdb = p.load(f)
97 print(accountdb)
98
99 def shelvefile():
100 """shelve"""
101 accountfile = 'shelve.data'
102 accountdb = s.open(accountfile, 'c')
103 accountdb['data'] = db
104 accountdb.close()
105
106 accountdb = s.open(accountfile, 'r')
107 print(accountdb['data'])
108
109 def adminlogin():
110 """管理员"""
111 while True:
112 name = input('Username:').lower()
113 if not name.isalnum() and '' in name:
114 print('name format error')
115 continue
116 else:
117 pwd = input('Password:')
118 if name == 'root' and pwd == 'root':
119 print('Welcom admin')
120 if len(db) == 0:
121 print('There is nothing you can do')
122 showmenu()
123 else:
124 while True:
125 answer = input('Output all account? y/n').lower()
126 if 'y' == answer:
127 prompt = "(T)ext\n(P)ickle\n(S)helve\n\nEnter choice:"
128 choice = input(prompt).lower()
129 if choice in 'tps':
130 if choice == 't': textfile()
131 if choice == 'p': picklefile()
132 if choice == 's': shelvefile()
133 elif 'n' == answer:
134 print('Bye')
135 showmenu()
136 sys.exit()
137 else:
138 print('User name or password is wrong, input again')
139
140
141 def showmenu():
142 """功能"""
143 prompt = """
144 (N)ew User Login
145 (E)xisting User Login
146 (G)et user
147 (R)emove a existing user
148 (A)dmin Login
149 (Q)uit
150
151 Enter choice: """
152
153 done = False
154 while not done:
155 chosen = False
156 while not chosen:
157 try:
158 choice = input(prompt).strip()[0].lower()
159 except (EOFError, KeyboardInterrupt):
160 choice = 'q'
161 print('\nYou picked: [%s]' % choice)
162 if choice not in 'negraq':
163 print('Invalid option, try again')
164 else:
165 chosen = True
166
167 if choice == 'q': done = True
168 if choice == 'n': newuser()
169 if choice == 'e': olduser()
170 if choice == 'g': getuser()
171 if choice == 'r': removeuser()
172 if choice == 'a': adminlogin()
173
174 if __name__ == '__main__':
175 showmenu()
9-14 记录结果。修改你的计算器程序(练习5-6)使之接受命令行参数。例如$ calc.py 1 + 2 只输出计算结果。另外,把每个表达式和它的结果写入到一个磁盘文件中,当使用下面的命令时 $ calc.py print 会把记录的内容显示到屏幕上,然后重置文件。这里是样例展示:
$ calc.py 1 + 2
3
$ calc.py 3 ^ 3
27
$ calc.py print
1 + 2
3
3 ^ 3
27
$ calc.py print
$
1 import sys, os
2
3 if sys.argv[1] == 'print':
4 if os.path.exists(r'test.txt'):
5 f = open(r'test.txt', 'r')
6 for line in f:
7 print(line)
8 f.close()
9 else:
10 print('No file yet')
11 f = open(r'text.txt', 'w')
12 f.close()
13 else:
14 print(sys.argv[1], sys.argv[2], sys.argv[3])
15 a, b = sys.argv[1], sys.argv[3]
16 operation = sys.argv[2]
17 expression = sys.argv[1] + '' + sys.argv[2] + '' + sys.argv[3] + os.linesep
18 f = open(r'test.txt', 'a+')
19 f.write(expression)
20 if '+' == operation:
21 print(float(a) + float(b))
22 result = str(float(a) + float(b)) + os.linesep
23 f.write(result)
24 elif '-' == operation:
25 print(float(a) - float(b))
26 result = str(float(a) - float(b)) + os.linesep
27 f.write(result)
28 elif '**' == operation:
29 print(float(a) ** float(b))
30 result = str(float(a) ** float(b)) + os.linesep
31 f.write(result)
32 elif '/' == operation:
33 print(float(a) / float(b))
34 result = str(float(a) / float(b)) + os.linesep
35 f.write(result)
36 elif '%' == operation:
37 print(float(a) % float(b))
38 result = str(float(a) % float(b)) + os.linesep
39 f.write(result)
40 elif '*' == operation:
41 print(float(a) - float(b))
42 result = str(float(a) * float(b)) + os.linesep
43 f.write(result)
44 f.close()
9–15. 复制文件. 提示输入两个文件名(或者使用命令行参数). 把第一个文件的内容复制到第二个文件中去.
1 filename1 = input("输入文件名1:")
2 filename2 = input("输入文件名2:")
3 with open(filename1) as f:
4 filelines = f.readlines()
5
6 with open(filename2, 'w') as f:
7 for fileline in filelines:
8 f.write(fileline)
9–16. 文本处理.
人们输入的文字常常超过屏幕的最大宽度. 编写一个程序, 在一个文本文件中查找长度大于 80 个字符的文本行. 从最接近 80 个字符的单词断行, 把剩余文件插入到下一行处.程序执行完毕后, 应该没有超过 80 个字符的文本行了.
1 filename = input("输入文件名:")
2 f1 = open(filename)
3 f = f1.readlines()
4 f1.close()
5
6 content = []
7 for line in f:
8 if len(line) > 80:
9 num = list(line)
10 count = len(num) // 80
11 for i in range(count+1):
12 content.append("".join(num[:79]) + '\n')
13 num = num[79:]
14 content.append("".join(num))
15 else:
16 content.append(line)
17
18 with open(filename, 'w') as f:
19 for fileline in content:
20 f.write(fileline)
21 print("Done")
9-17.文本处理 。创建一个原始的文本文件编辑器 。你的程序应该是菜单驱动的 ,有如下这些选项
1) 创建文件 (提示输入文件名和任意行的文本输入) :
2 ) 显示文件 (把文件的内容显示到屏幕):
3) 编辑文件 (提示输入要修改的行 ,然后让用户进行修改) :
4 ) 保存文件:
5 ) 退出。
1 import sys
2 import os
3
4 def create():
5 """创建文件"""
6 filename = input('输入文件名[b:返回]:')
7 if filename == 'b':
8 main()
9 while True:
10 text = input('输入内容[b:返回]:')
11 if text == 'b':
12 main()
13 with open(filename, 'a') as f:
14 f.write(text + '\n')
15 print("保存成功")
16
17 def display():
18 """显示文件"""
19 while True:
20 filename = input('输入文件名[b:返回]:')
21 if filename == 'b':
22 main()
23 with open(filename) as f:
24 for num, line in enumerate(f, 1):
25 print("第%d行:" % num, line, end='')
26 print('读取完毕')
27
28 def edit():
29 """编辑文件"""
30 filename = input('输入文件名[b:返回]:')
31 if filename == 'b':
32 main()
33 filelist = []
34 f = open(filename)
35 for num, line in enumerate(f, 1):
36 filelist.append(line)
37 print("第%d行:" % num, line, end='')
38 f.close()
39 print('读取完毕')
40
41 while True:
42 num = input("输入修改的行编号[b:返回]:")
43 if num == 'b':
44 main()
45 if int(num)-1 <= len(filelist):
46 text = input("输入内容:")
47 filelist[int(num)-1] = text + '\n'
48 with open(filename, 'w') as f:
49 for line in filelist:
50 f.write(line)
51 else:
52 print("输入有误")
53
54 def save():
55 """保存文件"""
56 while True:
57 for_mat = input("查看文件格式(如: .txt)[b:返回]:")
58 if for_mat == 'b':
59 main()
60 if for_mat not in str(os.listdir(os.getcwd())):
61 print("格式不存在")
62 else:
63 for foldername, subfolders, filename in os.walk(os.getcwd()):
64 print("已保存%s文件:\n%s" % (for_mat, '-' * 20))
65 for file in filename:
66 if file.endswith(for_mat):
67 print(file)
68 print("%s" % '-' * 20)
69
70 def main():
71 showmenu = ("""
72 [1]创建文件
73 [2]显示文件
74 [3]编辑文件
75 [4]保存文件
76 [5]退出
77
78 请输入编号:""")
79 while True:
80 num = input(showmenu)
81 if num == '5':
82 sys.exit()
83 elif num in '1234':
84 if num == '1': create()
85 if num == '2': display()
86 if num == '3': edit()
87 if num == '4': save()
88 else:
89 print("输入有误")
90
91 if __name__ == '__main__':
92 main()
9–18. 搜索文件. 提示输入一个字节值(0 - 255)和一个文件名. 显示该字符在文件中出现的次数.
1 num = int(input("输入数字(0-255):"))
2 filename = input("输入文件名:")
3 with open(filename) as f:
4 print(sum(line.count(chr(num)) for line in f))
9–20. 压缩文件.
写一小段代码, 压缩/解压缩 gzip 或 bzip 格式的文件. 可以使用命令行下的 gzip 或 bzip2 以及 GUI 程序 PowerArcHiver , StuffIt , 或 WinZip 来确认你的 Python支持这两个库.
1 import gzip
2
3 text = open(r'test.txt', 'rb')
4 gzipfile = gzip.open(r'test.txt.gz', 'wb')
5 gzipfile.writelines(text)
6 text.close()
7 gzipfile.close()
8
9 gzipfile = gzip.open(r'test.txt.gz', 'rb')
10 text = open(r'test1.txt', 'wb')
11 content = gzipfile.read()
12 text.write(content)
13 gzipfile.close()
14 text.close()
9–21. ZIP 归档文件.
创建一个程序, 可以往 ZIP 归档文件加入文件, 或从中提取文件,有可能的话, 加入创建ZIP 归档文件的功能.
1 import zipfile, sys
2
3 def archive_add():
4 """归档、添加"""
5 filename = input("压缩文件名[b:返回]:")
6 if filename == 'b':
7 main()
8 sys.exit()
9 while True:
10 file = input("文件名[b:返回]:")
11 if file == 'b':
12 archive_add()
13 filezip = zipfile.ZipFile(filename, 'a')
14 filezip.write(file)
15 filezip.close()
16 print('Done')
17
18 def extract():
19 """提取"""
20 filename = input("压缩文件名[b:返回]:")
21 if filename == 'b':
22 main()
23 sys.exit()
24 filezip = zipfile.ZipFile(filename)
25 print(filezip.namelist())
26 filezip.close()
27 while True:
28 file = input("文件名[b:返回]:")
29 if file == 'b':
30 extract()
31 filezip = zipfile.ZipFile(filename)
32 filezip.extract(file)
33 filezip.close()
34 print('Done')
35
36 def main():
37 menu = """
38 [1]归档、添加
39 [2]提取
40 [3]退出
41
42 请输入编号:"""
43
44 while True:
45 num = input(menu)
46 if num == '3':
47 break
48 elif num in '12':
49 if num == '1': archive_add()
50 if num == '2': extract()
51 else:
52 print('输入有误')
53
54 if __name__ == '__main__':
55 main()
9–22. ZIP 归档文件.
unzip -l 命令显示出的 ZIP 归档文件很无趣. 创建一个 Python脚本 lszip.py , 使它可以显示额外信息: 压缩文件大小, 每个文件的压缩比率(通过比较压缩前后文件大小), 以及完成的 time.ctime() 时间戳, 而不是只有日期和 HH:MM .
提示: 归档文件的 date_time 属性并不完整, 无法提供给 time.mktime() 使用....这由你自己决定.
1 import zipfile, time, os
2
3 filename = input("Zip file name:")
4 print('Zip file size:%d bytes' % (os.stat(filename)).st_size)
5 z = zipfile.ZipFile(filename)
6 print('filename\t\t\tdatetime\t\t\tsize\tcompress size\trate')
7 for info in z.infolist():
8 t = time.ctime(time.mktime(tuple(list(info.date_time) + [0, 0, 0])))
9 print('%8s\t%s\t%4d\t\t%4d\t\t%.2f%%' % (info.filename, t, info.file_size, info.compress_size,
10 float(info.compress_size / info.file_size * 100) ))
11 z.close()
9–23. TAR 归档文件.
为 TAR 归档文件建立类似上个问题的程序. 这两种文件的不同之处在于 ZIP 文件通常是压缩的, 而 TAR 文件不是, 只是在 gzip 和 bzip2 的支持下才能完成压缩工作. 加入任意一种压缩格式支持.附加题: 同时支持 gzip 和 bzip2 .
1 import tarfile, os
2
3 def compressfile(tarname, filename1, filename2):
4 t = tarfile.open(tarname, 'w:gz') #w.bz2
5 t.add(filename1)
6 t.add(filename2)
7 t.close()
8
9 def extractfile(tarname):
10 t = tarfile.open(tarname, 'r')
11 t.extractall(os.getcwd())
12 t.close()
13
14 if __name__ == '__main__':
15 compressfile(r'abc.tar.gz', r'a.txt', r'b.txt')#r'abc.tar.bz2'
16 extractfile(r'abc.tar.gz')#r'abc.tar.bz2'
9–24. 归档文件转换.
参考前两个问题的解决方案, 写一个程序, 在 ZIP (.zip) 和TAR/gzip (.tgz/.tar.gz) 或 TAR/bzip2 (.tbz/.tar.bz2) 归档文件间移动文件. 文件可能是已经存在的, 必要时请创建文件.
1 import zipfile, tarfile, os
2
3 def movefile(compressfile1, compressfile2, file):
4
5 if compressfile1.endswith('.zip') and compressfile2.endswith(('.tar.gz', '.tgz', '.tbz', '.tar.bz2')):
6 z = zipfile.ZipFile(compressfile1, 'a')
7 if file not in z.namelist():
8 f = open(file, 'w')
9 f.close()
10 z.write(file)
11 z.extract(file)
12 else:
13 z.extract(file)
14 z.close()
15 t = tarfile.open(compressfile2)
16 ls = t.getnames()
17 if file not in ls:
18 t.extractall()
19 t.close()
20 mode = 'w:gz' if compressfile2.endswith(('tar.gz', 'tgz')) else 'w:bz2'
21 t = tarfile.open(compressfile2, mode)
22 for name in ls + [file]:
23 t.add(name)
24 t.close()
25 os.remove(file)
26 t.close()
27
28 elif compressfile1.endswith(('.tar.gz', '.tgz', '.tbz', '.tar.bz2')) and compressfile2.endswith('.zip'):
29 t = tarfile.open(compressfile1)
30 if file not in t.getnames():
31 f = open(file, 'w')
32 f.close()
33 else:
34 t.extract(file)
35 t.close()
36 z = zipfile.ZipFile(compressfile2, 'a')
37 if file not in z.namelist():
38 z.write(file)
39 z.close()
40 os.remove(file)
41
42 if __name__ == '__main__':
43 compressfile1 = input('压缩文件名1:')
44 compressfile2 = input('压缩文件名2:')
45 file = input('文件名:')
46 movefile(compressfile1, compressfile2, file)
9–25. 通用解压程序.
创建一个程序, 接受任意数目的归档文件以及一个目标目录做为参数.归档文件格式可以是 .zip, .tgz, .tar.gz, .gz, .bz2, .tar.bz2, .tbz 中的一种或几种. 程序会把第一个归档文件解压后放入目标目录, 把其它归档文件解压后放入以对应文件名命名的目录下(不包括扩展名). 例如输入的文件名为 header.txt.gz 和 data.tgz , 目录为 incoming ,header.txt 会被解压到 incoming 而 data.tgz 中的文件会被放入 incoming/data .
1 import zipfile, tarfile, gzip, bz2, os
2
3 def extract(dir1, dir2):
4
5 filelist = os.listdir(dir1)
6 if filelist[0].endswith(('.tar.gz', '.tgz', '.tbz', '.tar.bz2')):
7 t = tarfile.open(os.path.join(dir1, filelist[0]))
8 t.extractall(dir2)
9 t.close()
10
11 elif filelist[0].endswith('.gz'):
12 g = gzip.open(os.path.join(dir1, filelist[0]), 'rb')
13 ug = open(os.path.join(dir2, os.path.splitext(filelist[0])[0]), 'wb')
14 data = g.read()
15 ug.write(data)
16 ug.close()
17 g.close()
18
19 elif filelist[0].endswith('.bz2'):
20 b = bz2.BZ2File(os.path.join(dir1, filelist[0]))
21 ub = open(os.path.join(dir2, os.path.splitext(filelist[0])[0]), 'wb')
22 data = b.read()
23 ub.write(data)
24 ub.close()
25 b.close()
26
27 elif filelist[0].endswith('.zip'):
28 z = zipfile.ZipFile(os.path.join(dir1, filelist[0]))
29 z.extractall(dir2)
30 z.close()
31
32 filelist.remove(filelist[0])
33
34 for file in filelist:
35
36 dirname = os.path.splitext(file)[0]
37
38 if dirname in os.listdir(dir2):
39 dirname = os.path.join(dir2, dirname, str(filelist.index(file)))
40 else:
41 dirname = os.path.join(dir2, dirname)
42 os.makedirs(dirname)
43
44 if file.endswith(('.tar.gz', '.tgz', '.tbz', '.tar.bz2')):
45 t = tarfile.open(os.path.join(dir1, file))
46 t.extractall(dirname)
47 t.close()
48
49 elif file.endswith('.gz'):
50 g = gzip.open(os.path.join(dir1, file), 'rb')
51 ug = open(os.path.join(dirname, os.path.splitext(file)[0]), 'wb')
52 data = g.read()
53 ug.write(data)
54 ug.close()
55 g.close()
56
57 elif file.endswith('.bz2'):
58 b = bz2.BZ2File(os.path.join(dir1, file))
59 ub = open(os.path.join(dirname, os.path.splitext(file)[0]), 'wb')
60 data = b.read()
61 ub.write(data)
62 ub.close()
63 b.close()
64
65 elif file.endswith('.zip'):
66 z = zipfile.ZipFile(os.path.join(dir1, file))
67 z.extractall(dirname)
68 z.close()
69
70 if __name__ == '__main__':
71 dir1 = os.path.abspath(input('Path1: '))
72 dir2 = os.path.abspath(input('Path2: '))
73 extract(dir1, dir2)
0