- 内容提要
- 作者简介
- 技术评审者简介
- 致谢
- 译者序 会编程的人不一样
- 前言
- 本书的读者对象
- 编码规范
- 什么是编程
- 本书简介
- 下载和安装 Python
- 启动 IDLE
- 如何寻求帮助
- 聪明地提出编程问题
- 小结
- 第一部分 Python 编程基础
- 第1章 Python 基础
- 第2章 控制流
- 第3章 函数
- 第4章 列表
- 第5章 字典和结构化数据
- 第6章 字符串操作
- 第二部分 自动化任务
- 第7章 模式匹配与正则表达式
- 第8章 读写文件
- 第9章 组织文件
- 第10章 调试
- 第11章 从 Web 抓取信息
- 第12章 处理 Excel 电子表格
- 第13章 处理 PDF 和 Word 文档
- 第14章 处理 CSV 文件和 JSON 数据
- 第15章 保持时间、计划任务和启动程序
- 第16章 发送电子邮件和短信
- 第17章 操作图像
- 第18章 用 GUI 自动化控制键盘和鼠标
- 附录A 安装第三方模块
- 附录B 运行程序
- 附录C 习题答案
9.5 项目:将一个文件夹备份到一个ZIP文件
假定你正在做一个项目,它的文件保存在C:\AlsPythonBook文件夹中。你担心工作会丢失,所以希望为整个文件夹创建一个ZIP文件,作为“快照”。你希望保存不同的版本,希望ZIP文件的文件名每次创建时都有所变化。例如AlsPythonBook_1.zip、AlsPythonBook_2.zip、AlsPythonBook_3.zip,等等。你可以手工完成,但这有点烦人,而且可能不小心弄错ZIP文件的编号。运行一个程序来完成这个烦人的任务会简单得多。
针对这个项目,打开一个新的文件编辑器窗口,将它保存为backupToZip.py。
第1步:弄清楚ZIP文件的名称
这个程序的代码将放在一个名为backupToZip()的函数中。这样就更容易将该函数复制粘贴到其他需要这个功能的Python程序中。在这个程序的末尾,会调用这个函数进行备份。让你的程序看起来像这样:
#! python3 # backupToZip.py - Copies an entire folder and its contents into # a ZIP file whose filename increments. ❶ import zipfile, os def backupToZip(folder): # Backup the entire contents of "folder" into a ZIP file. folder = os.path.abspath(folder) # make sure folder is absolute # Figure out the filename this code should use based on # what files already exist. ❷ number = 1 ❸ while True: zipFilename = os.path.basename(folder) + '_' + str(number) + '.zip' if not os.path.exists(zipFilename): break number = number + 1 ❹ # TODO: Create the ZIP file. # TODO: Walk the entire folder tree and compress the files in each folder. print('Done.') backupToZip('C:\\delicious')
先完成基本任务:添加#!行,描述该程序做什么,并导入zipfile和os模块❶。
定义backupToZip()函数,它只接收一个参数,即folder。这个参数是一个字符串路径,指向需要备份的文件夹。该函数将决定它创建的ZIP文件使用什么文件名,然后创建该文件,遍历folder文件夹,将每个子文件夹和文件添加到ZIP文件中。在源代码中为这些步骤写下TODO注释,提醒你稍后来完成❹。
第一部分命名这个ZIP文件,使用folder的绝对路径的基本名称。如果要备份的文件夹是C:\delicious,ZIP文件的名称就应该是delicious_N.zip,第一次运行该程序时N=1,第二次运行时N=2,以此类推。
通过检查delicious_1.zip是否存在,然后检查delicious_2.zip是否存在,继续下去,可以确定N应该是什么。用一个名为number的变量表示N❷,在一个循环内不断增加它,并调用os.path.exists()来检查该文件是否存在❸。第一个不存在的文件名将导致循环break,因此它就发现了新ZIP文件的文件名。
第2步:创建新ZIP文件
接下来让我们创建ZIP文件。让你的程序看起来像这样:
#! python3 # backupToZip.py - Copies an entire folder and its contents into # a ZIP file whose filename increments. --snip-- while True: zipFilename = os.path.basename(folder) + '_' + str(number) + '.zip' if not os.path.exists(zipFilename): break number = number + 1 # Create the ZIP file. print('Creating %s...' % (zipFilename)) ❶ backupZip = zipfile.ZipFile(zipFilename, 'w') # TODO: Walk the entire folder tree and compress the files in each folder. print('Done.') backupToZip('C:\\delicious')
既然新ZIP文件的文件名保存在zipFilename变量中,你就可以调用zipfile.ZipFile(),实际创建这个ZIP文件❶。确保传入'w'作为第二个参数,这样ZIP文件以写模式打开。
第3步:遍历目录树并添加到ZIP文件
现在需要使用os.walk()函数,列出文件夹以及子文件夹中的每个文件。让你的程序看起来像这样:
#! python3 # backupToZip.py - Copies an entire folder and its contents into # a ZIP file whose filename increments. --snip-- # Walk the entire folder tree and compress the files in each folder. ❶ for foldername, subfolders, filenames in os.walk(folder): print('Adding files in %s...' % (foldername)) # Add the current folder to the ZIP file. ❷ backupZip.write(foldername) # Add all the files in this folder to the ZIP file. ❸ for filename in filenames: newBase / os.path.basename(folder) + '_' if filename.startswith(newBase) and filename.endswith('.zip') continue # don't backup the backup ZIP files backupZip.write(os.path.join(foldername, filename)) backupZip.close() print('Done.') backupToZip('C:\\delicious')
可以在for循环中使用os.walk()❶,在每次迭代中,它将返回这次迭代当前的文件夹名称、这个文件夹中的子文件夹,以及这个文件夹中的文件名。
在这个for循环中,该文件夹被添加到ZIP文件❷。嵌套的for循环将遍历filenames列表中的每个文件❸。每个文件都被添加到ZIP文件中,以前生成的备份ZIP文件除外。
如果运行该程序,它产生的输出看起来像这样:
Creating delicious_1.zip... Adding files in C:\delicious... Adding files in C:\delicious\cats... Adding files in C:\delicious\waffles... Adding files in C:\delicious\walnut... Adding files in C:\delicious\walnut\waffles... Done.
第二次运行它时,它将C:\delicious中的所有文件放进一个ZIP文件,命名为delicious_2.zip,以此类推。
第4步:类似程序的想法
你可以在其他程序中遍历一个目录树,将文件添加到压缩的ZIP归档文件中。例如,你可以编程做下面的事情:
· 遍历一个目录树,将特定扩展名的文件归档,诸如.txt或.py,并排除其他文件。
· 遍历一个目录树,将除.txt和.py文件以外的其他文件归档。
· 在一个目录树中查找文件夹,它包含的文件数最多,或者使用的磁盘空间最大。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论