您的位置:首页 > 编程语言 > Python开发

《Python核心编程》第9章 习题

2015-11-22 21:00 519 查看
9–1. 文件过滤. 显示一个文件的所有行, 忽略以井号( # )开头的行. 这个字符被用做Python , Perl, Tcl, 等大多脚本文件的注释符号.附加题: 处理不是第一个字符开头的注释.

f=open('test.txt','r')
for eachline in f:
if eachline.startswith('#'):
continue
elif '#' in eachline:
loc=eachline.find('#')
print eachline[:loc]
else:
print eachline,
f.close()
9–2. 文件访问. 提示输入数字 N 和文件 F, 然后显示文件 F 的前 N 行.

N=int(raw_input('pls input a number:'))
F=raw_input('pls input a file name:')
f=open(F,'r')
alllines=f.readlines()
f.close()
for i in range(N):
print alllines[i],
9–3. 文件信息. 提示输入一个文件名, 然后显示这个文本文件的总行数.

F=raw_input('pls input a file name:')
f=open(F,'r')
alllines=f.readlines()
f.close()
print len(alllines)
9–4. 文件访问.

写一个逐页显示文本文件的程序. 提示输入一个文件名, 每次显示文本文件的 25 行, 暂停并向用户提示"按任意键继续.", 按键后继续执行.
import os
F=raw_input('pls input a file name:')
n=0
f=open(F,'r')
for i in f:
print i,
n+=1
if n==25:
n=0
os.system('pause')
f.close()
9-5 考试成绩,改进你的考试成绩问题(练习5-3和6-4),要求能从多个文件中读入考试成绩。文件的数据格式由你自己决定。

f=open('test.txt','r')
scores=[]
for i in f:
if 0<=int(i.strip())<=100:
scores.append(int(i.strip()))
if int(i.strip())<60:
print 'score is F' ,i
elif 60<=int(i.strip())<=69:
print 'score is D',i
elif 70<=int(i.strip())<=79:
print 'score is C',i
elif 80<=int(i.strip())<=89:
print 'score is B',i
elif 90<=int(i.strip())<=100:
print 'score is A',i
else:
print 'score wrong,please input again',i
f.close()
print 'average score is %f' %(sum(scores)//len(scores))
9–6. 文件比较. 写一个比较两个文本文件的程序. 如果不同, 给出第一个不同处的行号和列号.

F1=raw_input('pls input a file name:')
F2=raw_input('pls input a file name:')
f1=open(F1,'r')
f1alllines=f1.readlines()
f1.close()
f2=open(F2,'r')
f2alllines=f2.readlines()
f2.close()
len1=len(f1alllines)
len2=len(f2alllines)
smallfile=len1 if len1<=len2 else len2
for i in range(smallfile):
if cmp(f1alllines[i],f2alllines[i])!=0:
print 'row is %d ' %(i+1)
len3=len(f1alllines[i])
len4=len(f2alllines[i])
smallstr=len3 if len3<=len4 else len4
for j in range(smallstr):
if cmp(f1alllines[i][j],f2alllines[i][j])!=0:
print 'column is %d ' %(j+1)
break
break
else:
if len1==len2:
print '2 files equal'
else:
print 'row is %d ' %(i+2)
9–7. 解析文件. Win32 用户: 创建一个用来解析 Windows .ini 文件的程序. POSIX 用户:创建一个解析 /etc/serves 文件的程序. 其它平台用户: 写一个解析特定结构的系统配置文件的程序.

option={}
f=open(r'c:\windows\win.ini')
for line in f:
if line.startswith(';'):
continue
if line.startswith('['):
iterm=[]
name = line[1:line.rfind(']')]
option.setdefault(name,iterm)
continue
if '=' in line:
option[name].append(line.strip())
print option
9–8. 模块研究. 提取模块的属性资料. 提示用户输入一个模块名(或者从命令行接受输入).然后使用 dir() 和其它内建函数提取模块的属性, 显示它们的名字, 类型, 值.

m=raw_input('pls input a module name: ')
module=__import__(m)
ml=dir(module)
print ml
for i in ml:
print 'name: ',i
print 'type: ',type(getattr(module,i))
print 'value: ',getattr(module,i)
print
9–9. Python 文档字符串.

进入 Python 标准库所在的目录. 检查每个 .py 文件看是否有__doc__ 字符串, 如果有, 对其格式进行适当的整理归类. 你的程序执行完毕后, 应该会生成一个漂亮的清单. 里边列出哪些模块有文档字符串, 以及文档字符串的内容. 清单最后附上那些没有文档字符串模块的名字.附加题: 提取标准库中各模块内全部类(class)和函数的文档.
import os
pymodules={}
path=r'D:\Program Files\Python27\Lib'
pyfiles=[f for f in os.listdir(path) if f.endswith('.py')]
for f in pyfiles:
module=f[:-3]
pymodules.setdefault(module,'')
pyfile=path+os.sep+f
fobj=open(pyfile)
doc=False
for line in fobj:
if line.strip().startswith('"""') and line.strip().endswith('"""'):
pymodules[module]+=line
fobj.close()
break
elif (line.strip().startswith('"""') or line.strip().startswith('r"""')) and len(line)>3:
doc=True
pymodules[module]+=line
continue
elif doc:
if line=='"""':
pymodules[module]+=line
fobj.close()
doc=False
break
else:
pymodules[module]+=line
else:
continue
else:
fobj.close()

hasdoc=[]
nodoc=[]
for module in pymodules:
if pymodules[module]:
hasdoc.append(module)
else:
nodoc.append(module)

print 'module has no doc:'
for key in nodoc:
print key,
print '\n'
print 'module has doc:'
for key in hasdoc:
print 'module:',key
print 'doc:',pymodules[key]
9-10 不会

9–11. Web 站点地址.

a) 编写一个 URL 书签管理程序. 使用基于文本的菜单, 用户可以添加, 修改或者删除书签数据项. 书签数据项中包含站点的名称, URL 地址, 以及一行简单说明(可选). 另外提供检索功能,可以根据检索关键字在站点名称和 URL 两部分查找可能的匹配. 程序退出时把数据保存到一个磁盘文件中去; 再次执行时候加载保存的数据.

b)改进 a) 的解决方案, 把书签输出到一个合法且语法正确的 HTML 文件(.html 或 htm )中,这样用户就可以使用浏览器查看自己的书签清单. 另外提供创建"文件夹"功能, 对相关的书签进行分组管理.

附加题: 请阅读 Python 的 re 模块了解有关正则表达式的资料, 使用正则表达式对用户输入的 URL 进行验证.

import re,os

def checkurl(url):
regex = re.compile(
r'^(?:http|ftp)s?://' # http:// or https:// r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' #domain...
r'localhost|' #localhost...
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
r'(?::\d+)?' # optional port
r'(?:/?|[/?]\S+)$', re.IGNORECASE)
if regex.match(url):
return True
else:
return False

def geturl():
name=raw_input('pls input a url name:')
while 1:
url=raw_input('pls input a url address:')
if checkurl(url):
break
else:
print 'wrong url format,pls input again'
mark=raw_input('pls input a url mark:')
folder=raw_input('pls input a url folder:')
return (name,url,mark,folder)

def load(filename):
f=open(filename,'a+')
bmlist=f.readlines()
f.close()
return bmlist

def save(bmlist,filename):
f=open(filename,'w+')
for line in bmlist:
if len(line)==0:
continue
f.write(line)
f.close()

def add(bmlist,name,url,mark,folder='default'):
bookmark=''
bookmark=name+';'+url+';'+mark+';'+folder+os.linesep
if bookmark not in bmlist:
bmlist.append(bookmark)

def modify(bmlist,index,name,url,mark,folder):
bookmark=''
bookmark=name+';'+url+';'+mark+';'+folder+os.linesep
bmlist[index]=bk

def delbm(bmlist,index):
bmlist.pop(index)

def findbk(bmlist,fname,furl):
for i,item in enumerate(bmlist):
(name,url,mark,folder)=item.split(';')
if fname and furl:
if (fname in name) and (furl in url):
return i
if fname and (fname in name):
return i
if furl and (furl in url):
return i
else:
return -1

def output2html(bmlist):
for i,item in enumerate(bmlist):
(name, url, mark, folder) = item.split(';')
os.mkdir(folder.strip())
filename=name.strip()+'.html'
f=open(filename,'w+')
fmt = '%d\t%s\t<a href=%s>%s</a>\t%s\t%s<br>'
f.write('<html><head><title>bookmark</title></head><body>')
content = fmt % (i+1, name, r'http:\\' + url, url, mark, folder)
f.write(content)
f.write('</body></html>')
f.close()
os.rename(filename,folder.strip()+os.sep+filename)

bmlist=load(r'url.txt')
print bmlist
while True:
print '0. quit'
print '1. add a url bookmark'
print '2. modify a url bookmark'
print '3. delete a url bookmark'
print '4. find a url bookmark'
print '5. output url bookmark as html'
print '\n'

iInput = input("please input operation num: ")
if (0 == iInput):
save(bmlist,r'url.txt')
break
elif (iInput<0 or iInput>5):
print 'Error input operation, try agin. 0 operation is quit\n'
continue
elif 1 == iInput:
data=geturl()
add(bmlist,*data)
print bmlist
elif 2 == iInput:
index=int(raw_input('bookmark index:'))
data=geturl()
modify(bmlist,index,*data)
print bmlist
elif 3 == iInput:
index=int(raw_input('bookmark index:'))
delbm(bmlist,index)
print bmlist
elif 4 == iInput:
name=raw_input('url name:')
url=raw_input('url address:')
index=findbk(bmlist,name,url)
if index==-1:
print 'not found'
else:
print bmlist[index]
elif 5 == iInput:
output2html(bmlist)
9-12 用户名和密码。回顾练习7-5,修改代码使之可以支持“上次登录时间”。请参阅time模块中的文档了解如何记录用户上次登录的时间。另外提供一个系统管理员,他可以导出所有用户的用户名,密码(如需要可以加密),以及上次登录时间。

a)数据应保存在磁盘中,使用冒号:分隔,一次写入一行,例如“Joe:boohoo:953176591.145,文件中数据的行数应该等于你系统上的用户数。

b)进一步改进你的程序,不再一次写入一行,而使用pickle模块保存整个数据对象。请参阅pickle模块的文档了解如何序列化/扁平化对象,以及如何读写保存的对象。一般来说,这个解决方案的代码行数要比a)少;

c)使用shelve模块替换pickle模块,由于可以省去一些维护代码,这个解决方案的代码比b)的更少。

from datetime import datetime
import hashlib,os
import pickle as p
import shelve as s

db={}
def newuser():
value=[]
prompt='login name desired again: '
while True:
name=raw_input(prompt).lower()
if not name.isalnum() and '' in name:
print 'name format error'
continue
else:
if db.has_key(name):
prompt='name taken,try another: '
continue
else:
break
pwd=raw_input('login passwd desired: ')
m=hashlib.md5()
m.update(pwd)
value.append(m.hexdigest())
value.append(datetime.now())
db[name]=value
print 'new user is %s, register time is %s' %(name,db[name][1])

def olduser():
name=raw_input('login name desired again: ').lower()
pwd=raw_input('login passwd desired: ')
m=hashlib.md5()
m.update(pwd)
passwd=db.get(name)
if passwd[0]==m.hexdigest():
newtime=datetime.now()
if (newtime-db[name][1]).days==0 and (newtime-db[name][1]).seconds<14400:
print 'you already logged in at %s: ' %(db[name][1])
else:
passwd[1]=newtime
print 'welcome back %s, login time is %s' %(name,passwd[1])

else:
print 'login incorrect'

def removeuser():
print db
name=raw_input('input a user name to remove: ').lower()
if name in db:
db.pop(name)
else:
print 'input error'

def userlogin():
while True:
name=raw_input('login name desired: ').lower()
if not name.isalnum() and '' in name:
print 'name format error'
continue
else:
if not db.has_key(name):
print 'user name is not in db'
answer=raw_input('register a new user? y/n').lower()
if 'y'==answer:
newuser()
break
elif 'n'==answer:
break
else:
print 'user name is already in db'
olduser()
break

def outputA():
print db
f=open('account.txt','w')
for key in db:
user=key+':'+db[key][0]+':'+str(db[key][1])+os.linesep
f.write(user)
f.close()

def outputB():
accountfile='pickle.data'
f=open(accountfile,'w')
p.dump(db,f)
f.close()

f=open(accountfile)
accountdb=p.load(f)
print accountdb

def outputC():
accountfile='shelve.data'
accountdb=s.open(accountfile,'c')
accountdb['data']=db
accountdb.close()

accountdb=s.open(accountfile,'r')
print accountdb['data']

def adminlogin():
while True:
name=raw_input('login name desired: ').lower()
if not name.isalnum() and '' in name:
print 'name format error'
continue
else:
pwd=raw_input('login passwd desired: ')
if name=='root' and pwd=='root':
print 'welcom admin'
break
else:
print 'user name or passwd is wrong,input again'
if len(db)==0:
print 'there is nothing you can do'
else:
answer=raw_input('output all account? y/n').lower()
if 'y'==answer:
#outputA()
#outputB()
outputC()
elif 'n'==answer:
print 'bye'

def showmenu():
prompt="""
(A)dmin Login
(U)ser Login
(R)emove a existing user
(Q)uit
Enter choice:"""

done=False
while not done:
chosen=False
while not chosen:
try:
choice=raw_input(prompt).strip()[0].lower()
except (EOFError,keyboardInterrupt):
choice='q'
print '\nYou picked: [%s]' % choice
if choice not in 'aurq':
print 'invalid option,try again'
else:
chosen=True

if choice=='q':
done=True
if choice=='r':
removeuser()
if choice=='u':
userlogin()
if choice=='a':
adminlogin()

if __name__=='__main__':
showmenu()
9–13. 命令行参数

a) 什么是命令行参数, 它们有什么用?

命令行参数是调用某个程序时除程序名以外的其他参数。命令行参数使程序员可以在启动一个程序时对程序行为作出选择。

b) 写一个程序, 打印出所有的命令行参数.

import sys
print str(sys.argv)
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

$

import sys,os

if sys.argv[1]=='print':
if os.path.exists(r'test.txt'):
f=open(r'test.txt','r')
for line in f:
print line
f.close()
else:
print 'no file yet'
f=open(r'test.txt','w')
f.close()
else:
print sys.argv[1],sys.argv[2],sys.argv[3]
a,b=sys.argv[1],sys.argv[3]
operation=sys.argv[2]
expression=sys.argv[1]+''+sys.argv[2]+''+sys.argv[3]+os.linesep
f=open(r'test.txt','a+')
f.write(expression)
if '+' == operation:
print float(a)+float(b)
result=str(float(a)+float(b))+os.linesep+os.linesep
f.write(result)
elif '-' == operation:
print float(a)-float(b)
result=str(float(a)-float(b))+os.linesep+os.linesep
f.write(result)
elif '**' == operation:
print float(a)**float(b)
result=str(float(a)**float(b))+os.linesep+os.linesep
f.write(result)
elif '/' == operation:
print float(a)/float(b)
result=str(float(a)/float(b))+os.linesep+os.linesep
f.write(result)
elif '%' == operation:
print float(a)%float(b)
result=str(float(a)%float(b))+os.linesep+os.linesep
f.write(result)
elif '*' == operation:
print float(a)*float(b)
result=str(float(a)*float(b))+os.linesep+os.linesep
f.write(result)
f.close()
9–15. 复制文件. 提示输入两个文件名(或者使用命令行参数). 把第一个文件的内容复制到第二个文件中去.

import os
file1=raw_input('input first file name:')
file2=raw_input('input second file name:')

f1=open(file1,'r')
f2=open(file2,'a+')
f2.write(os.linesep)
for line in f1:
f2.write(line)
f1.close()
f2.close()
9–16. 文本处理.

人们输入的文字常常超过屏幕的最大宽度. 编写一个程序, 在一个文本文件中查找长度大于 80 个字符的文本行. 从最接近 80 个字符的单词断行, 把剩余文件插入到下一行处.程序执行完毕后, 应该没有超过 80 个字符的文本行了.
import os

content=[]
f=open(r'test.txt','r')
lines=f.readlines()
f.close()

for line in lines:
if len(line)<=80:
content.append(line)
else:
words=line.strip().split()
sum=0
l=''
for w in words:
w+=' '
sum+=len(w)
if sum<80:
l+=w
else:
content.append(l)
l=w
sum=len(w)
else:
content.append(l)
l=''

f=open(r'test1.txt','w')
for item in content:
f.write(item+os.linesep)
f.close()
9–17. 文本处理.

创建一个原始的文本文件编辑器. 你的程序应该是菜单驱动的, 有如下这些选项:

1) 创建文件(提示输入文件名和任意行的文本输入),

2) 显示文件(把文件的内容显示到屏幕),

3) 编辑文件(提示输入要修改的行, 然后让用户进行修改),

4) 保存文件, 以及

5) 退出.
import os

def create(filename):
content=[]
while True:
line=raw_input('pls input a line,quit as e:')
if line != 'e':
content.append(line)
else:
break
f=open(filename,'w')
for line in content:
f.write(line+os.linesep)
f.close()

def show(filename):
if os.path.exists(filename):
f=open(filename)
for line in f:
print line,
f.close()
else:
print 'no file yet'

def edit(filename,index,content):
f=open(filename)
ls=f.readlines()
f.close()
ls[index]=content
return ls

def save(filename,ls):
f=open(filename,'w')
for line in ls:
f.write(line)
f.close()

def main():
filename=''
ls=[]
while True:
print '\n'
print '1. create a file'
print '2. show a file'
print '3. edit a file'
print '4. save a file'
print '5. quit'

ch=raw_input('input a choice:')
if ch not in '1234':
break
elif ch=='1':
filename=raw_input('input a file name:')
create(filename)
elif ch=='2':
filename=raw_input('input a file name:')
show(filename)
elif ch=='3':
if filename == '':
filename = raw_input('file name: ')
index=int(raw_input('input a index of line:'))
content=raw_input('pls input a line:')
ls=edit(filename,index,content)
elif ch=='4':
save(filename,ls)

if __name__=='__main__':
main()
9–18. 搜索文件. 提示输入一个字节值(0 - 255)和一个文件名. 显示该字符在文件中出现的次数.

value=int(raw_input('input a value between 0 and 255:'))
filename=raw_input('input a fielname:')

ch=chr(value)
f=open(filename)
print sum(iterm.count(ch) for iterm in f)
f.close()
9–19. 创建文件.

创建前一个问题的辅助程序. 创建一个随机字节的二进制数据文件, 但某一特定字节会在文件中出现指定的次数. 该程序接受三个参数:

1) 一个字节值( 0 - 255 ),

2) 该字符在数据文件中出现的次数, 以及

3) 数据文件的总字节长度.

你的工作就是生成这个文件, 把给定的字节随机散布在文件里, 并且要求保证给定字符在文件中只出现指定的次数, 文件应精确地达到要求的长度.
import random
def createfile(value,count,len):
ls=[]
n=len-count
for i in range(n):
ran=random.randint(0,255)
if ran!=value:
ls.append(chr(ran))
elif ran==value and value==0:
ran=random.randint(1,255)
ls.append(chr(ran))
elif ran==value and value==255:
ran=random.randint(0,254)
ls.append(chr(ran))
elif ran==value:
ran=random.randint(0,value-1)
ls.append(chr(ran))
for i in range(count):
ls.insert(random.randint(0,n),chr(value))
f=open(r'test.txt','wb')
f.write(''.join(ls))
f.close()
createfile(97,3,50)
f=open(r'test.txt','rb')
for i in f:
print i
f.seek(0,0)
print len(f.readlines()[0])
f.close()
9–20. 压缩文件.

写一小段代码, 压缩/解压缩 gzip 或 bzip 格式的文件. 可以使用命令行下的 gzip 或 bzip2 以及 GUI 程序 PowerArchiver , StuffIt , 或 WinZip 来确认你的 Python支持这两个库.
import gzip
#compress
f_in=open(r'test.txt','rb')
f_out=gzip.open(r'test.txt.gz','wb')
f_out.writelines(f_in)
f_out.close()
f_in.close()
#decompress
f=gzip.open(r'test.txt.gz','rb')
f_out=open(r'test1.txt','wb')
content=f.read()
f_out.write(content)
f.close()
f_out.close()
9–21. ZIP 归档文件.

创建一个程序, 可以往 ZIP 归档文件加入文件, 或从中提取文件,有可能的话, 加入创建ZIP 归档文件的功能.
import zipfile
def create_zipfile(zipname,filename1,filename2):
z=zipfile.ZipFile(zipname,'w')
z.write(filename1)
z.write(filename2)
z.close()

def add_zipfile(zipname,filename):
z=zipfile.ZipFile(zipname,'a')
z.write(filename)
z.close()

def extract_zipfile(zipname,filename):
z=zipfile.ZipFile(zipname,'r')
z.extract(filename)
z.close()

if __name__=='__main__':
create_zipfile(r'test.zip',r'test.txt',r'test1.txt')
add_zipfile(r'test.zip',r'test2.txt')
extract_zipfile(r'test.zip',r'test.txt')
9–22. ZIP 归档文件.

unzip -l 命令显示出的 ZIP 归档文件很无趣. 创建一个 Python脚本 lszip.py , 使它可以显示额外信息: 压缩文件大小, 每个文件的压缩比率(通过比较压缩前后文件大小), 以及完成的 time.ctime() 时间戳, 而不是只有日期和 HH:MM .

提示: 归档文件的 date_time 属性并不完整, 无法提供给 time.mktime() 使用....这由你自己决定.
import zipfile,os,time

filename=raw_input('zip file name:')
print 'zip file size: %d bytes' %(os.stat(filename).st_size)
z=zipfile.ZipFile(filename,'r')
print 'filename\tdatetime\tsize\tcompress size\trate'
for info in z.infolist():
t = time.ctime(time.mktime(tuple(list(info.date_time) + [0, 0, 0])))
print '%s\t%s\t%d\t%d\t%.2f%%' %(info.filename, t, info.file_size, info.compress_size, float(info.compress_size) / info.file_size * 100)
z.close()
9–23. TAR 归档文件.

为 TAR 归档文件建立类似上个问题的程序. 这两种文件的不同之处在于 ZIP 文件通常是压缩的, 而 TAR 文件不是, 只是在 gzip 和 bzip2 的支持下才能完成压缩工作. 加入任意一种压缩格式支持.附加题: 同时支持 gzip 和 bzip2 .
import tarfile
def create_tarfile(tarname,filename1,filename2):
t=tarfile.open(tarname,'w:gz')#w:bz2
t.add(filename1)
t.add(filename2)
t.close()

def extract_tarfile(tarname):
t=tarfile.open(tarname,'r')
t.extractall(r'D:\test')
t.close()

if __name__=='__main__':
create_tarfile(r'test.tar.gz',r'test.txt',r'test1.txt')
extract_tarfile(r'test.tar.gz')
9–24. 归档文件转换.

参考前两个问题的解决方案, 写一个程序, 在 ZIP (.zip) 和TAR/gzip (.tgz/.tar.gz) 或 TAR/bzip2 (.tbz/.tar.bz2) 归档文件间移动文件. 文件可能是已经存在的, 必要时请创建文件.
import zipfile,tarfile,os

def movefile(src,dst,filename):
if src.endswith('.zip') and dst.endswith(('.tar.gz', '.tgz', '.tbz', '.tar.bz2')):
z=zipfile.ZipFile(src,'a')
if filename not in z.namelist():
f=open(filename,'w')
f.close()
z.write(filename)
z.extract(filename)
else:
z.extract(filename)
z.close()
t=tarfile.open(dst,'r')
ls=t.getnames()
if filename not in ls:
t.extractall()
t.close()
mode='w:gz' if dst.endswith(('tar.gz','tgz')) else 'w:bz2'
t=tarfile.open(dst,mode)
for name in ls+[filename]:
t.add(name)
os.remove(name)
t.close()
t.close()
elif src.endswith(('.tar.gz', '.tgz', '.tbz', '.tar.bz2')) and dst.endswith(('.zip')):
t=tarfile.open(src,'r')
if filename not in t.getnames():
f=open(filename,'w')
f.close()
else:
t.extract(filename)
t.close()
z=zipfile.ZipFile(dst,'a')
if filename not in z.namelist():
z.write(filename)
z.close()
os.remove(filename)

if __name__=='__main__':
movefile(r'test.zip',r'test.tar.gz',r'test2.txt')
movefile(r'test.tar.gz',r'test.zip',r'test2.txt')
9–25. 通用解压程序.

创建一个程序, 接受任意数目的归档文件以及一个目标目录做为参数.归档文件格式可以是 .zip, .tgz, .tar.gz, .gz, .bz2, .tar.bz2, .tbz 中的一种或几种. 程序会把第一个归档文件解压后放入目标目录, 把其它归档文件解压后放入以对应文件名命名的目录下(不包括扩展名). 例如输入的文件名为 header.txt.gz 和 data.tgz , 目录为 incoming ,header.txt 会被解压到 incoming 而 data.tgz 中的文件会被放入 incoming/data
.
import zipfile,tarfile,gzip,bz2,os

def depressfile(src,dst):
if os.path.isdir(src):
filenames=os.listdir(src)
if filenames[0].endswith(('.tar.gz', '.tgz', '.tbz', '.tar.bz2')):
t=tarfile.open(src+os.sep+filenames[0],'r')
t.extractall(dst)
t.close()
elif filenames[0].endswith('.gz'):
g=gzip.open(src+os.sep+filenames[0],'rb')
ug=open(dst+os.sep+filenames[0][:-3],'wb')
data=g.read()
ug.write(data)
ug.close()
g.close()
elif filenames[0].endswith('.bz2'):
b=bz2.BZ2File(src+os.sep+filenames[0],'r')
ub=open(dst+os.sep+filenames[0][:-4],'w')
data=b.read()
ub.write(data)
ub.close()
b.close()
elif filenames[0].endswith('.zip'):
z=zipfile.ZipFile(src+os.sep+filenames[0],'r')
z.extractall(dst)
z.close()
filenames.remove(filenames[0])
for name in filenames:
dirname = os.path.splitext(os.path.basename(name))[0]
if dirname in os.listdir(dst):
dirname = dst+os.sep+dirname+str(filenames.index(name))
else:
dirname = dst+os.sep+dirname
os.mkdir(dirname)
if name.endswith(('.tar.gz', '.tgz', '.tbz', '.tar.bz2')):
t=tarfile.open(src+os.sep+name,'r')
t.extractall(dirname)
t.close()
elif name.endswith('.gz'):
g=gzip.open(src+os.sep+name,'rb')
ug=open(dirname+os.sep+name[:-3],'wb')
data=g.read()
ug.write(data)
ug.close()
g.close()
elif name.endswith('.bz2'):
b=bz2.BZ2File(src+os.sep+name,'r')
ub=open(dirname+os.sep+name[:-4],'w')
data=b.read()
ub.write(data)
ub.close()
b.close()
elif name.endswith('.zip'):
z=zipfile.ZipFile(src+os.sep+name,'r')
z.extractall(dirname)
z.close()
else:
print '%s is not a directory,input again' %(src)

if __name__=='__main__':
depressfile(r'D:\1',r'D:\2')
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: