如果您在linux和windows之间共享文件,那么python zip文件库会出现问题



使用python管理.zip文件时,zipfile模块非常有趣。

但是,如果.zip文件是在linux系统或macos上创建的,分隔符当然是"/",如果我们试图在Windows系统上使用此文件,则可能会出现问题,因为分隔符是"\"。因此,例如,如果我们试图确定.zip文件中压缩的目录根,我们可以考虑以下内容:

from zipfile import ZipFile, is_zipfile
import os
if is_zipfile(filename):
with ZipFile(filename, 'r') as zip_ref:
packages_name = [member.split(os.sep)[0] for member in zip_ref.namelist()
if (len(member.split(os.sep)) == 2 and not
member.split(os.sep)[-1])]

但在这种情况下,我们总是得到packet_name=[],因为os.sep是"\"而由于压缩是在linux系统上完成的,因此路径相当于"foo1/foo2"。

为了管理所有情况(在linux系统上压缩,在Windows系统上使用或相反(,我想使用:

from zipfile import ZipFile, is_zipfile
import os
if is_zipfile(filename):
with ZipFile(filename, 'r') as zip_ref:
if all([True if '/' in el else
False for el in zip_ref.namelist()]):
packages_name = [member.split('/')[0] for member in zip_ref.namelist()
if (len(member.split('/')) == 2 and not
member.split('/')[-1])]
else:
packages_name = [member.split('\')[0] for member in zip_ref.namelist()
if (len(member.split('\')) == 2 and not
member.split('\')[-1])]

你觉得这怎么样?有没有更直接或更像蟒蛇的方法来做这项工作?

感谢@sakecharmerb的回答和他提出的链接的阅读,我才刚刚理解。谢谢你@sakecharmerb给我带路。。。事实上,正如所提出的链接中所描述的,zipfile内部只使用"/",这与所使用的操作系统无关。由于我喜欢具体地看待事情,我只是做了一个小测试:

  • 在一个Windows操作系统上,我用这个操作系统的常用方法(不在命令行中(创建了一个包含以下树结构的文件testZipWindows.zip:

    • 测试ZipWindows
      • foo1.txt
      • InFolder
        • foo2.txt
  • 我在linux操作系统上为testZipFedora.zip档案做了同样的事情(也没有使用命令行(:

    • 测试ZipFedora
      • foo1.txt
      • InFolder
        • foo2.txt

这是结果:

$ python3
Python 3.7.9 (default, Aug 19 2020, 17:05:11) 
[GCC 9.3.1 20200408 (Red Hat 9.3.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from zipfile import ZipFile
>>> with ZipFile('/home/servoz/Desktop/test/testZipWindows.zip', 'r') as WinZip:
...  WinZip.namelist()
... 
['testZipWindows/', 'testZipWindows/foo1.txt', 'testZipWindows/InFolder/', 'testZipWindows/InFolder/foo2.txt']
>>> with ZipFile('/home/servoz/Desktop/test/testZipFedora.zip', 'r') as fedZip:
...  fedZip.namelist()
... 
['testZipFedora/', 'testZipFedora/foo1.txt', 'testZipFedora/InFolder/', 'testZipFedora/InFolder/foo2.txt']

一切都亮了!我们确实必须使用os.path.sep才能在多平台中正常工作,但当我们处理zip文件库时,绝对有必要使用"/"作为分隔符,而不是os.sep(或os.path.sep(。这是我的错误!!!

因此,对于我第一篇文章的例子,以多平台方式使用的代码只是:

from zipfile import ZipFile, is_zipfile
import os
if is_zipfile(filename):
with ZipFile(filename, 'r') as zip_ref:
packages_name = [member.split('/')[0] for member in zip_ref.namelist()
if (len(member.split('/')) == 2 and not
member.split('/')[-1])]

并不是我想象中的所有无用的东西。。。

最新更新