Python comprime una subcarpeta y no la ruta completa de la carpeta

Tengo un progtwig para comprimir todos los contenidos en una carpeta. No escribí este código, pero lo encontré en algún lugar en línea y lo estoy usando. Tengo la intención de comprimir una carpeta, por ejemplo, C: / folder1 / folder2 / folder3 /. Quiero comprimir la carpeta3 y todo su contenido en un archivo, por ejemplo, carpeta 3.zip. Con el siguiente código, una vez comprimido, el contenido de folder3.zip será folder1 / folder2 / folder3 / and files. No quiero que la ruta completa esté comprimida y solo quiero que la subcarpeta esté interesada en comprimir (carpeta3 en este caso). Probé algunos os.chdir, etc., pero no tuve suerte.

def makeArchive(fileList, archive): """ 'fileList' is a list of file names - full path each name 'archive' is the file name for the archive with a full path """ try: a = zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED) for f in fileList: print "archiving file %s" % (f) a.write(f) a.close() return True except: return False def dirEntries(dir_name, subdir, *args): # Creates a list of all files in the folder '''Return a list of file names found in directory 'dir_name' If 'subdir' is True, recursively access subdirectories under 'dir_name'. Additional arguments, if any, are file extensions to match filenames. Matched file names are added to the list. If there are no additional arguments, all files found in the directory are added to the list. Example usage: fileList = dirEntries(r'H:\TEMP', False, 'txt', 'py') Only files with 'txt' and 'py' extensions will be added to the list. Example usage: fileList = dirEntries(r'H:\TEMP', True) All files and all the files in subdirectories under H:\TEMP will be added to the list. ''' fileList = [] for file in os.listdir(dir_name): dirfile = os.path.join(dir_name, file) if os.path.isfile(dirfile): if not args: fileList.append(dirfile) else: if os.path.splitext(dirfile)[1][1:] in args: fileList.append(dirfile) # recursively access file names in subdirectories elif os.path.isdir(dirfile) and subdir: print "Accessing directory:", dirfile fileList.extend(dirEntries(dirfile, subdir, *args)) return fileList 

Puede llamar a esto mediante makeArchive(dirEntries(folder, True), zipname) .

¿Alguna idea sobre cómo resolver este problema? Estoy usando Windows y Python 25, sé que en Python 2.7 hay shutil make_archive que ayuda pero como estoy trabajando en 2.5 necesito otra solución: – /

Tendrá que dar un argumento de ZipFile.write() de ZipFile.write() a ZipFile.write() que usa una ruta relativa. Haga esto dando la ruta de acceso raíz para eliminar a makeArchive() :

 def makeArchive(fileList, archive, root): """ 'fileList' is a list of file names - full path each name 'archive' is the file name for the archive with a full path """ a = zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED) for f in fileList: print "archiving file %s" % (f) a.write(f, os.path.relpath(f, root)) a.close() 

y llama a esto con:

 makeArchive(dirEntries(folder, True), zipname, folder) 

He quitado la manta try: except: :; No hay ningún uso para eso aquí y solo sirve para ocultar los problemas que desea conocer.

La función os.path.relpath() devuelve una ruta relativa a la root , eliminando efectivamente esa ruta raíz de la entrada del archivo.

En Python 2.5, la función relpath no está disponible; para este caso de uso específico funcionaría el siguiente reemplazo:

 def relpath(filename, root): return filename[len(root):].lstrip(os.path.sep).lstrip(os.path.altsep) 

y use:

 a.write(f, relpath(f, root)) 

Tenga en cuenta que la función relpath() solo funciona para su caso específico donde se garantiza que filepath comience con la root ; En Windows, el caso general de relpath() es mucho más complejo. Realmente quieres actualizar a Python 2.6 o más nuevo si es posible.

ZipFile.write tiene un argumento opcional nombre de arcname . Utilice esto para eliminar partes de la ruta.

Podrías cambiar tu método para ser:

 def makeArchive(fileList, archive, path_prefix=None): """ 'fileList' is a list of file names - full path each name 'archive' is the file name for the archive with a full path """ try: a = zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED) for f in fileList: print "archiving file %s" % (f) if path_prefix is None: a.write(f) else: a.write(f, f[len(path_prefix):] if f.startswith(path_prefix) else f) a.close() return True except: return False 

Sin embargo, el enfoque de Martijn usando os.path es mucho más elegante.