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 option9–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) print9–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. 命令行参数
命令行参数是调用某个程序时除程序名以外的其他参数。命令行参数使程序员可以在启动一个程序时对程序行为作出选择。
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')