谁说Python的shutil不支持7z解压缩,我来教你扩展它的功能!
python的内置模块
在Python的标准库中,有哪些你常用并且觉得犀利无比的模块?不要说time、datetime、os、sys。这些模块常用是常用,但是逼格不够高啊。举个例子,如果你经常在LeetCode上刷题,你会发现有时Java、C需要几十行的算法题,如果Python使用了collections、itertools,可能三四行代码就结束了。
shutil的便利
日常的编码中,常会涉及到对文件、目录等的操作场景,如果我们使用os,可能需要对文件、文件夹,非空等进行逐个判断。举个例子: 我们现在要删除一个目录,目录中包含有文件与文件夹,如果使用os模块,没有现成可以使用的函数,需要我们进行判断与分类执行。
import os # path是文件的路径,如果这个路径是一个文件夹, # 则会抛出OSError的错误,这时需用用rmdir()来删除 os.remove(path) # path是文件夹路径,注意文件夹需空的才能被删除 os.rmdir(path)
多数初学者遇到删除文件夹,想到的操作就是,创建两个列表,然后用os.walk遍历目录,将文件与文件夹分别存入初始化的两个列表中,然后先统一删除文件,最后删除文件夹。如果有上面这样操作的同学,请面壁三分钟。明显没有好好学习os.walk函数。
os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]]) top -- 是你所要遍历的目录的地址, 返回的是一个三元组(root,dirs,files)。 root 所指的是当前正在遍历的这个文件夹的本身的地址 dirs 是一个 list ,内容是该文件夹中所有的目录的名字(不包括子目录) files 同样是 list , 内容是该文件夹中所有的文件(不包括子目录) topdown --可选,为 True,则优先遍历 top 目录,否则优先遍历 top 的子目录(默认为开启)。如果 topdown 参数为 True,walk 会遍历top文件夹, 与top 文件夹中每一个子目录。 onerror -- 可选,需要一个 callable 对象,当 walk 需要异常时,会调用。 followlinks -- 可选,如果为 True,则会遍历目录下的快捷方式(linux 下是软连接 symbolic link )实际所指的目录(默认关闭),如果为 False,则优先遍历 top 的子目录。
只需要将topdown设置为False,这样在遍历目录时,就会从根节点进行遍历,然后我们逐个删除就ok了,哪里需要那么麻烦!代码如下:
import os for root, dirs, files in os.walk('D:\\software_temp', topdown=False): for name in files: os.remove(os.path.join(root, name)) for name in dirs: os.rmdir(os.path.join(root, name))
说这么多,无外乎为了引出最简便的方式 : shutil模块
如果换做shutil模块登场,那么执行删除目录的操作,只需要0.1秒的时间:
import shutil shutil.rmtree('D:\\software_temp')
就这样,完事儿了...
文件文件解压缩解压缩
日常工作中,我们经常会使用python进行文件的解压缩处理。python自带的解压缩模块有zipfile, gzip, tarfile,如果我们需要解压rar文件则需要单独下载rarfile模块,针对每一种压缩文件,我们都需要针对文件类型进行对应模块的使用,是不是很繁琐?如果我们使用shutil呢?让我们先来看看shutil支持的解压类型:
import pprint import shutil pprint.pprint(shutil.get_unpack_formats()) output: [('bztar', ['.tar.bz2', '.tbz2'], "bzip2'ed tar-file"), ('gztar', ['.tar.gz', '.tgz'], "gzip'ed tar-file"), ('tar', ['.tar'], 'uncompressed tar file'), ('xztar', ['.tar.xz', '.txz'], "xz'ed tar-file"), ('zip', ['.zip'], 'ZIP file')]
shutil已经包含了我们上面提到的所有文件。
.7z文件是什么鬼?
众所周知,zip的压缩率相比rar是比较低的,但是商业软件下载中,你很少会见到.rar的文件,why?因为专利啊...
RAR是一种专利文件格式,用于数据压缩与归档打包,开发者为尤金·罗谢尔(俄语:Евгений Лазаревич Рошал,拉丁转写:Yevgeny Lazarevich Roshal),RAR的全名是“Roshal ARchive”,即“罗谢尔的归档”之意。首个公开版本RAR 1.3发布于1993年。
所以,有很多产品在软件发布时,开始使用一种压缩率更高的.7z文件,这又是为什么?来让我们访问一下7-zip的官网:7-zip官方主页:https://sparanoid.com/lab/7z/在其中有一个许可协议是这样写的
许可协议:
7-Zip 是一款 开源 软件。大多数源代码都基于 GNU LGPL 许可协议下发布。AES 代码基于 BSD 许可下发布。unRAR 代码基于两种许可:GNU LGPL 和 unRAR 限制许可。更多下许可信息请查看:7-Zip 许可。您可以在任何一台计算机上使用 7-Zip ,包括用在商业用途的计算机,不对 7-Zip 进行捐赠或支付并不影响您的使用。
shutil扩展7z
说了这么多7z文件的好处,可我们看到shutil并不能解压该类型的文件啊。我们能否让shutil支持.7z文件,达到无脑解压缩呢?此时,你需要py7zr模块。养成好习惯,遇到模块先找GitHub:https://github.com/miurahr/py7zr
1. 模块下载
pip install py7zr
2. 基本使用
当我们安装好py7zr后,它可以在cmd下直接运行该命令
List archive contents $ py7zr l test.7z Extract archive $ py7zr x test.7z Extract archive with password $ py7zr x -P test.7z password?: **** Create and compress to archive $ py7zr c target.7z test_dir Create multi-volume archive $ py7zr c -v 500k target.7z test_dir Test archive $ py7zr t test.7z Show information $ py7zr i Show version $ py7zr --version
单独使用模块
import py7zr archive = py7zr.SevenZipFile('sample.7z', mode='r') archive.extractall(path="/tmp") archive.close() with py7zr.SevenZipFile('target.7z', 'w') as z: z.writeall('./base_dir')
3. shutil集成
之所以推荐py7zr给大家,不仅因为他的简单好用,更是由于他可以轻松集成于shutil,来看看它的使用方式吧:
from py7zr import pack_7zarchvie, unpack_7zarchive import shutil # register file format at first. shutil.register_archive_format('7zip', pack_7zarchive, description='7zip archive') shutil.register_unpack_format('7zip', ['.7z'], unpack_7zarchive, description='7zip archive') # extraction shutil.unpack_archive('test.7z', '/tmp') # compression shutil.make_archive('target', '7zip', 'src') pprint.pprint(shutil.get_unpack_formats()) # output: [('7zip', ['.7z'], '7zip archive'), ('bztar', ['.tar.bz2', '.tbz2'], "bzip2'ed tar-file"), ('gztar', ['.tar.gz', '.tgz'], "gzip'ed tar-file"), ('tar', ['.tar'], 'uncompressed tar file'), ('xztar', ['.tar.xz', '.txz'], "xz'ed tar-file"), ('zip', ['.zip'], 'ZIP file')]
通过注册我们看到,shutil已经支持7z文件的解压了,就是如此简单。
--------------------
本文转自“清风Python”公众号
- 点赞
- 收藏
- 关注作者
评论(0)