如何在python中压缩文件

问题描述:

如何压缩python中的文件以及如何指定压缩级别?如何在python中压缩文件

我有下面的代码,到目前为止,我得到的错误是:

Zip("log4j.dl-service.log.2013-05-03-22",9) 
AttributeError: 'str' object has no attribute 'ZipFile' 

代码:

import zipfile 
import fileinput 

def Zip(file,level): 
    """ 
    This function uses the zip library native to python to compress files with 
    Usage: Zip(file,level) 
    """ 

    if file and level: 
     try: 
      zipfile = file+'.zip' 
      output = zipfile.ZipFile(zipfile, 'wb') 
      for line in fileinput.input(file): 
       output.write(line) 
      output.close() 
      if os.path.exists(zipfile): 
       return zipfile 
      else: 
       logMe('critical',"zip failed in Zip()") 
       return False 

     except Exception,e: 
      logMe('critical',e) 
+7

答:不要使用与您的进口相同的变量名称,只是要求麻烦。 B:不要使用与您的输入相同的变量名称,否则无法阅读。 C:不要使用与您的导入相同的变量名称。 – 2013-05-07 19:34:02

+0

@JeffLangemeier:你应该把它写成一个答案(多一点信息),因为......好吧,这就是答案。 – abarnert 2013-05-07 19:34:47

+1

@SimplySeth:请发布整个回溯,而不仅仅是错误消息。在这种情况下,我们可以很容易地猜测,因为碰巧只有一个地方你试图访问任何名为'ZipFile'的属性,但为什么让我们猜测呢? – abarnert 2013-05-07 19:36:37

这里的问题是这一行:

zipfile = file+'.zip' 

之后,zipfile不再指模块,但此字符串。所以,当你这样做:

output = zipfile.ZipFile(zipfile, 'wb') 

你问一个字符串,而不是一个模块,叫ZipFile

因此这个错误:

AttributeError: 'str' object has no attribute 'ZipFile' 

修复的方法是不要让你的变量zipfile

杰夫Langemeier说,关键是:

Don't use variable names that are the same as your imports that's just asking for trouble. B: Don't use variable names that are the same as your imports it makes it impossible to read. C: Don't use variable names that are the same as your imports.

更一般地,没有为两个不同的东西使用相同的名称。


关于第二个问题:

how do specify the compression level

你不能。这是故意的,出于同样的原因,zip命令行工具不再记录10个压缩级别,只有-0用于存储(不压缩),用于“压缩更好”。几乎从来没有任何东西,除了商店或默认使用。 通常不会比默认压缩更好 - 或者压缩某些文件效果更好,而其他压缩效果更差。如果您需要更好的压缩,则需要更好的算法 - 例如,使用.tar.bz2而不是.zip,或使用p7zip(它可以创建与zip兼容的文件)而不是简单的zip

所以,Python的库只给你两个选择:store或default。作为the docs显示:

class zipfile.ZipFile(file[, mode[, compression[, allowZip64]]])

compression is the ZIP compression method to use when writing the archive, and should be ZIP_STORED or ZIP_DEFLATED

且同样write/writestr方法。

如果你真的想这样做,你可以直接调用zlib.compress,直接创建一个ZipInfo对象,并将其添加到存档自己。如果你看the source(从文档链接),你可以看到writestr做什么 - 一旦你删除所有不相关的条件和类型检查,它真的不复杂。

但是真的,我不认为你想这样做。

+0

我只是添加了这个,因为我认为@JeffLangemeier不会回答。我打算删除它,但现在已经两次提高。我想它提供了一些额外的解释,但杰夫发现了问题并首先提供了答案。 – abarnert 2013-05-07 19:40:42

+0

个人而言,我更喜欢你的,我无法清楚地表达答案。 – 2013-05-07 19:40:48

+0

@JeffLangemeier:我认为“不要使用与您的导入相同的变量名”非常清楚。我喜欢重复,每次都有不同的原因。 – abarnert 2013-05-07 19:42:09

所以,我想我的意见是,答案为好。

您的变量本质上是将调用“重载”到导入的方法,从而导致代码的一些非常糟糕的消耗。因此,请遵循以下规则:

答:请勿使用与您的导入相同的变量名称,这只是为了解决问题。 B:不要使用与您的导入相同的变量名称,因为它不可能读取。 C:不要使用与导入相同的变量名称。

如果你按照这个要求,它会为你和你问很多头痛的人节省。如果您选择将其关闭,请使用下划线来分隔zip_file或filezip或其他任何内容。