¿Cómo crear un archivo zip de un directorio en Python?

492

¿Cómo puedo crear un archivo zip de una estructura de directorio en Python?

Martha Yi
fuente
21
No utilice la solución sugerida en la respuesta aceptada, pero cuanto más abajo usando make_archivedesde shutil(si se desea comprimir un único directorio de forma recursiva).
Malana

Respuestas:

527

Como otros han señalado, debe usar zipfile . La documentación le dice qué funciones están disponibles, pero en realidad no explica cómo puede usarlas para comprimir un directorio completo. Creo que es más fácil de explicar con un código de ejemplo:

#!/usr/bin/env python
import os
import zipfile

def zipdir(path, ziph):
    # ziph is zipfile handle
    for root, dirs, files in os.walk(path):
        for file in files:
            ziph.write(os.path.join(root, file))

if __name__ == '__main__':
    zipf = zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED)
    zipdir('tmp/', zipf)
    zipf.close()

Adaptado de: http://www.devshed.com/c/a/Python/Python-UnZipped/

Mark Byers
fuente
129129
Añadiría un segundo argumento a la llamada de escritura, pasando os.path.relpath(os.path.join(root, file), os.path.join(path, '..')). Eso le permitiría comprimir un directorio desde cualquier directorio de trabajo, sin obtener las rutas absolutas completas en el archivo.
Reembolsar el
8
Hay una recurrencia divertida cuando intento comprimir una carpeta y enviar el zip resultante a la misma carpeta. :-)
Sibbs Gambling
13
shutillo hace realmente fácil en una sola línea. Por favor, compruebe la respuesta a continuación ..
droidlabour
77
puede estar más interesado haciendo ziph.write (os.path.join (ruta, archivo), arcname = archivo) para que los nombres de archivo dentro del archivo no sean relativos al disco duro
Christophe Blin
1
Ah, me estaba perdiendo la .close()llamada!
information_interchange
1066

La forma más fácil es usarlo shutil.make_archive. Es compatible con los formatos zip y tar.

import shutil
shutil.make_archive(output_filename, 'zip', dir_name)

Si necesita hacer algo más complicado que comprimir todo el directorio (como omitir ciertos archivos), deberá profundizar en el zipfilemódulo como otros han sugerido.

crdavis
fuente
113
shutiles parte de la biblioteca estándar de python. Esta debería ser la respuesta principal
AlexG
44
Esta es la respuesta más concisa aquí y también tiene la ventaja de agregar todos los subdirectorios y archivos al archivo directamente, en lugar de tener todo incluido en una carpeta de nivel superior (lo que resulta en un nivel redundante en la estructura de la carpeta al descomprimir).
aitch-hat
3
@cmcginty, ¿podría ser un poco más específico en cuanto a qué aspecto no es seguro para subprocesos? ¿Ejecutar varios subprocesos mientras uno llama a esto hará que el intérprete se bloquee?
std''OrgnlDave
13
Tenga en cuenta que antes de Python 3.4, shutil.make_archive no es compatible con ZIP64 y fallará al crear archivos ZIP de más de 2 GB.
azdev
2
@Teekin No. Si observa el informe de errores (bugs.python.org/issue30511), verá que se shutil.make_archiveutiliza os.chdir(). Por lo que estoy leyendo os.chdir(), funciona a nivel mundial.
Sam Malayek
65

Para agregar el contenido de mydirectoryun nuevo archivo zip, incluidos todos los archivos y subdirectorios:

import os
import zipfile

zf = zipfile.ZipFile("myzipfile.zip", "w")
for dirname, subdirs, files in os.walk("mydirectory"):
    zf.write(dirname)
    for filename in files:
        zf.write(os.path.join(dirname, filename))
zf.close()
Ben James
fuente
Para mí, este código arroja el siguiente error TypeError: archivo no válido: <zipfile.ZipFile [cerrado]>
Nishad Up
10
¿No puedes usar un en withlugar de tener que llamarte close()al final?
ArtOfWarfare
50

¿Cómo puedo crear un archivo zip de una estructura de directorio en Python?

En un script de Python

En Python 2.7+, shutiltiene una make_archivefunción.

from shutil import make_archive
make_archive(
  'zipfile_name', 
  'zip',           # the archive format - or tar, bztar, gztar 
  root_dir=None,   # root for archive - current working dir if None
  base_dir=None)   # start archiving from here - cwd if None too

Aquí se nombrará el archivo comprimido zipfile_name.zip. Si base_direstá más abajo root_dir, excluirá los archivos que no estén en el base_dir, pero aún archivará los archivos en los directorios principales hastaroot_dir .

Tuve un problema al probar esto en Cygwin con 2.7; quiere un argumento root_dir, para cwd:

make_archive('zipfile_name', 'zip', root_dir='.')

Usando Python desde el shell

Puedes hacer esto con Python desde el shell también usando el zipfilemódulo:

$ python -m zipfile -c zipname sourcedir

¿Dónde zipnameestá el nombre del archivo de destino que desea (agregue.zip si lo desea, no lo hará automáticamente) y sourcedir es la ruta al directorio.

Comprimir Python (o simplemente no quiere el directorio padre):

Si está intentando comprimir un paquete de Python con un __init__.pyy __main__.py, y no quiere el directorio principal, es

$ python -m zipfile -c zipname sourcedir/*

Y

$ python zipname

correría el paquete. (Tenga en cuenta que no puede ejecutar subpaquetes como punto de entrada desde un archivo comprimido).

Comprimir una aplicación Python:

Si tiene python3.5 + y específicamente desea comprimir un paquete de Python, use zipapp :

$ python -m zipapp myapp
$ python myapp.pyz
Aaron Hall
fuente
32

Esta función comprimirá recursivamente un árbol de directorios, comprimirá los archivos y registrará los nombres de archivo relativos correctos en el archivo. Las entradas de archivo son las mismas que las generadas por zip -r output.zip source_dir.

import os
import zipfile
def make_zipfile(output_filename, source_dir):
    relroot = os.path.abspath(os.path.join(source_dir, os.pardir))
    with zipfile.ZipFile(output_filename, "w", zipfile.ZIP_DEFLATED) as zip:
        for root, dirs, files in os.walk(source_dir):
            # add directory (needed for empty dirs)
            zip.write(root, os.path.relpath(root, relroot))
            for file in files:
                filename = os.path.join(root, file)
                if os.path.isfile(filename): # regular files only
                    arcname = os.path.join(os.path.relpath(root, relroot), file)
                    zip.write(filename, arcname)
George V. Reilly
fuente
17

Utilice shutil, que forma parte del conjunto de bibliotecas estándar de Python. Usar shutil es muy simple (vea el código a continuación):

  • 1er argumento: Nombre de archivo del archivo zip / tar resultante,
  • 2do argumento: zip / tar,
  • 3er argumento: dir_name

Código:

import shutil
shutil.make_archive('/home/user/Desktop/Filename','zip','/home/username/Desktop/Directory')
vadiraj jahagirdar
fuente
12

Para agregar compresión al archivo zip resultante, consulte este enlace .

Necesitas cambiar:

zip = zipfile.ZipFile('Python.zip', 'w')

a

zip = zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED)
E Smith
fuente
5

He realizado algunos cambios en el código dados por Mark Byers . La siguiente función también agregará directorios vacíos si los tiene. Los ejemplos deberían dejar más claro cuál es la ruta agregada al zip.

#!/usr/bin/env python
import os
import zipfile

def addDirToZip(zipHandle, path, basePath=""):
    """
    Adding directory given by \a path to opened zip file \a zipHandle

    @param basePath path that will be removed from \a path when adding to archive

    Examples:
        # add whole "dir" to "test.zip" (when you open "test.zip" you will see only "dir")
        zipHandle = zipfile.ZipFile('test.zip', 'w')
        addDirToZip(zipHandle, 'dir')
        zipHandle.close()

        # add contents of "dir" to "test.zip" (when you open "test.zip" you will see only it's contents)
        zipHandle = zipfile.ZipFile('test.zip', 'w')
        addDirToZip(zipHandle, 'dir', 'dir')
        zipHandle.close()

        # add contents of "dir/subdir" to "test.zip" (when you open "test.zip" you will see only contents of "subdir")
        zipHandle = zipfile.ZipFile('test.zip', 'w')
        addDirToZip(zipHandle, 'dir/subdir', 'dir/subdir')
        zipHandle.close()

        # add whole "dir/subdir" to "test.zip" (when you open "test.zip" you will see only "subdir")
        zipHandle = zipfile.ZipFile('test.zip', 'w')
        addDirToZip(zipHandle, 'dir/subdir', 'dir')
        zipHandle.close()

        # add whole "dir/subdir" with full path to "test.zip" (when you open "test.zip" you will see only "dir" and inside it only "subdir")
        zipHandle = zipfile.ZipFile('test.zip', 'w')
        addDirToZip(zipHandle, 'dir/subdir')
        zipHandle.close()

        # add whole "dir" and "otherDir" (with full path) to "test.zip" (when you open "test.zip" you will see only "dir" and "otherDir")
        zipHandle = zipfile.ZipFile('test.zip', 'w')
        addDirToZip(zipHandle, 'dir')
        addDirToZip(zipHandle, 'otherDir')
        zipHandle.close()
    """
    basePath = basePath.rstrip("\\/") + ""
    basePath = basePath.rstrip("\\/")
    for root, dirs, files in os.walk(path):
        # add dir itself (needed for empty dirs
        zipHandle.write(os.path.join(root, "."))
        # add files
        for file in files:
            filePath = os.path.join(root, file)
            inZipPath = filePath.replace(basePath, "", 1).lstrip("\\/")
            #print filePath + " , " + inZipPath
            zipHandle.write(filePath, inZipPath)

Arriba hay una función simple que debería funcionar para casos simples. Puedes encontrar una clase más elegante en mi Gist: https://gist.github.com/Eccenux/17526123107ca0ac28e6

Nux
fuente
1
El manejo de la ruta podría simplificarse enormemente usando os.path . Mira mi respuesta.
George V. Reilly
Error: zipHandle.write (os.path.join (root, ".")) No tiene en cuenta basePath.
Petter
Sí, probablemente tengas razón. Más tarde he mejorado esto un poco ;-) gist.github.com/Eccenux/17526123107ca0ac28e6
Nux
4

Python moderno (3.6+) que usa el pathlibmódulo para el manejo conciso de rutas de tipo OOP y pathlib.Path.rglob()para el engrosamiento recursivo. Por lo que puedo decir, esto es equivalente a la respuesta de George V. Reilly: comprime con compresión, el elemento superior es un directorio, mantiene directorios vacíos, usa rutas relativas.

from pathlib import Path
from zipfile import ZIP_DEFLATED, ZipFile

from os import PathLike
from typing import Union


def zip_dir(zip_name: str, source_dir: Union[str, PathLike]):
    src_path = Path(source_dir).expanduser().resolve(strict=True)
    with ZipFile(zip_name, 'w', ZIP_DEFLATED) as zf:
        for file in src_path.rglob('*'):
            zf.write(file, file.relative_to(src_path.parent))

Nota: como indican las sugerencias de tipo opcionales, zip_nameno puede ser un objeto Path ( se solucionaría en 3.6.2+ ).

tiempo de monje
fuente
1
¡Fantástico! ¡Conciso! ¡Moderno!
ingyhere
3

Tengo otro ejemplo de código que puede ayudar, usando python3, pathlib y zipfile. Debería funcionar en cualquier sistema operativo.

from pathlib import Path
import zipfile
from datetime import datetime

DATE_FORMAT = '%y%m%d'


def date_str():
    """returns the today string year, month, day"""
    return '{}'.format(datetime.now().strftime(DATE_FORMAT))


def zip_name(path):
    """returns the zip filename as string"""
    cur_dir = Path(path).resolve()
    parent_dir = cur_dir.parents[0]
    zip_filename = '{}/{}_{}.zip'.format(parent_dir, cur_dir.name, date_str())
    p_zip = Path(zip_filename)
    n = 1
    while p_zip.exists():
        zip_filename = ('{}/{}_{}_{}.zip'.format(parent_dir, cur_dir.name,
                                             date_str(), n))
        p_zip = Path(zip_filename)
        n += 1
    return zip_filename


def all_files(path):
    """iterator returns all files and folders from path as absolute path string
    """
    for child in Path(path).iterdir():
        yield str(child)
        if child.is_dir():
            for grand_child in all_files(str(child)):
                yield str(Path(grand_child))


def zip_dir(path):
    """generate a zip"""
    zip_filename = zip_name(path)
    zip_file = zipfile.ZipFile(zip_filename, 'w')
    print('create:', zip_filename)
    for file in all_files(path):
        print('adding... ', file)
        zip_file.write(file)
    zip_file.close()


if __name__ == '__main__':
    zip_dir('.')
    print('end!')
Duncanmonty
fuente
1

Aquí hay una variación en la respuesta dada por Nux que funciona para mí:

def WriteDirectoryToZipFile( zipHandle, srcPath, zipLocalPath = "", zipOperation = zipfile.ZIP_DEFLATED ):
    basePath = os.path.split( srcPath )[ 0 ]
    for root, dirs, files in os.walk( srcPath ):
        p = os.path.join( zipLocalPath, root [ ( len( basePath ) + 1 ) : ] )
        # add dir
        zipHandle.write( root, p, zipOperation )
        # add files
        for f in files:
            filePath = os.path.join( root, f )
            fileInZipPath = os.path.join( p, f )
            zipHandle.write( filePath, fileInZipPath, zipOperation )
M Katz
fuente
1

Prueba el siguiente. Funcionó para mí .

import zipfile, os
zipf = "compress.zip"  
def main():
    directory = r"Filepath"
    toZip(directory)
def toZip(directory):
    zippedHelp = zipfile.ZipFile(zipf, "w", compression=zipfile.ZIP_DEFLATED )

    list = os.listdir(directory)
    for file_list in list:
        file_name = os.path.join(directory,file_list)

        if os.path.isfile(file_name):
            print file_name
            zippedHelp.write(file_name)
        else:
            addFolderToZip(zippedHelp,file_list,directory)
            print "---------------Directory Found-----------------------"
    zippedHelp.close()

def addFolderToZip(zippedHelp,folder,directory):
    path=os.path.join(directory,folder)
    print path
    file_list=os.listdir(path)
    for file_name in file_list:
        file_path=os.path.join(path,file_name)
        if os.path.isfile(file_path):
            zippedHelp.write(file_path)
        elif os.path.isdir(file_name):
            print "------------------sub directory found--------------------"
            addFolderToZip(zippedHelp,file_name,path)


if __name__=="__main__":
    main()
Chandra
fuente
1

Si desea una funcionalidad como la carpeta de compresión de cualquier administrador de archivos gráfico común, puede usar el siguiente código, que utiliza el módulo zipfile . Con este código, tendrá el archivo zip con la ruta como su carpeta raíz.

import os
import zipfile

def zipdir(path, ziph):
    # Iterate all the directories and files
    for root, dirs, files in os.walk(path):
        # Create a prefix variable with the folder structure inside the path folder. 
        # So if a file is at the path directory will be at the root directory of the zip file
        # so the prefix will be empty. If the file belongs to a containing folder of path folder 
        # then the prefix will be that folder.
        if root.replace(path,'') == '':
                prefix = ''
        else:
                # Keep the folder structure after the path folder, append a '/' at the end 
                # and remome the first character, if it is a '/' in order to have a path like 
                # folder1/folder2/file.txt
                prefix = root.replace(path, '') + '/'
                if (prefix[0] == '/'):
                        prefix = prefix[1:]
        for filename in files:
                actual_file_path = root + '/' + filename
                zipped_file_path = prefix + filename
                zipf.write( actual_file_path, zipped_file_path)


zipf = zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED)
zipdir('/tmp/justtest/', zipf)
zipf.close()
VGe0rge
fuente
1

Para dar más flexibilidad, por ejemplo, seleccione el directorio / archivo por nombre use:

import os
import zipfile

def zipall(ob, path, rel=""):
    basename = os.path.basename(path)
    if os.path.isdir(path):
        if rel == "":
            rel = basename
        ob.write(path, os.path.join(rel))
        for root, dirs, files in os.walk(path):
            for d in dirs:
                zipall(ob, os.path.join(root, d), os.path.join(rel, d))
            for f in files:
                ob.write(os.path.join(root, f), os.path.join(rel, f))
            break
    elif os.path.isfile(path):
        ob.write(path, os.path.join(rel, basename))
    else:
        pass

Para un árbol de archivos:

.
├── dir
   ├── dir2
      └── file2.txt
   ├── dir3
      └── file3.txt
   └── file.txt
├── dir4
   ├── dir5
   └── file4.txt
├── listdir.zip
├── main.py
├── root.txt
└── selective.zip

Puede, por ejemplo, seleccionar solo dir4y root.txt:

cwd = os.getcwd()
files = [os.path.join(cwd, f) for f in ['dir4', 'root.txt']]

with zipfile.ZipFile("selective.zip", "w" ) as myzip:
    for f in files:
        zipall(myzip, f)

O simplemente listdiren el directorio de invocación de script y agregue todo desde allí:

with zipfile.ZipFile("listdir.zip", "w" ) as myzip:
    for f in os.listdir():
        if f == "listdir.zip":
            # Creating a listdir.zip in the same directory
            # will include listdir.zip inside itself, beware of this
            continue
        zipall(myzip, f)
pbn
fuente
Esto se cierra, pero no se comprime.
Alex
1

Supongamos que desea comprimir todas las carpetas (subdirectorios) en el directorio actual.

for root, dirs, files in os.walk("."):
    for sub_dir in dirs:
        zip_you_want = sub_dir+".zip"
        zip_process = zipfile.ZipFile(zip_you_want, "w", zipfile.ZIP_DEFLATED)
        zip_process.write(file_you_want_to_include)
        zip_process.close()

        print("Successfully zipped directory: {sub_dir}".format(sub_dir=sub_dir))
ShiningGo
fuente
1

Para una forma concisa de retener la jerarquía de carpetas en el directorio principal que se archivará:

import glob
import zipfile

with zipfile.ZipFile(fp_zip, "w", zipfile.ZIP_DEFLATED) as zipf:
    for fp in glob(os.path.join(parent, "**/*")):
        base = os.path.commonpath([parent, fp])
        zipf.write(fp, arcname=fp.replace(base, ""))

Si lo desea, puede cambiar esto para usarlo pathlib para el almacenamiento de archivos .

ryanjdillon
fuente
1

Tantas respuestas aquí, y espero poder contribuir con mi propia versión, que se basa en la respuesta original (por cierto), pero con una perspectiva más gráfica, también usando el contexto para cada zipfileconfiguración y clasificación os.walk(), para tener un salida ordenada

Teniendo estas carpetas y sus archivos (entre otras carpetas), quería crear un .zippara cada cap_carpeta:

$ tree -d
.
├── cap_01
|    ├── 0101000001.json
|    ├── 0101000002.json
|    ├── 0101000003.json
|
├── cap_02
|    ├── 0201000001.json
|    ├── 0201000002.json
|    ├── 0201001003.json
|
├── cap_03
|    ├── 0301000001.json
|    ├── 0301000002.json
|    ├── 0301000003.json
| 
├── docs
|    ├── map.txt
|    ├── main_data.xml
|
├── core_files
     ├── core_master
     ├── core_slave

Esto es lo que apliqué, con comentarios para una mejor comprensión del proceso.

$ cat zip_cap_dirs.py 
""" Zip 'cap_*' directories. """           
import os                                                                       
import zipfile as zf                                                            


for root, dirs, files in sorted(os.walk('.')):                                                                                               
    if 'cap_' in root:                                                          
        print(f"Compressing: {root}")                                           
        # Defining .zip name, according to Capítulo.                            
        cap_dir_zip = '{}.zip'.format(root)                                     
        # Opening zipfile context for current root dir.                         
        with zf.ZipFile(cap_dir_zip, 'w', zf.ZIP_DEFLATED) as new_zip:          
            # Iterating over os.walk list of files for the current root dir.    
            for f in files:                                                     
                # Defining relative path to files from current root dir.        
                f_path = os.path.join(root, f)                                  
                # Writing the file on the .zip file of the context              
                new_zip.write(f_path) 

Básicamente, para cada iteración os.walk(path), estoy abriendo un contexto para la zipfileconfiguración y luego, iterando iterando files, que es un listarchivo de rootdirectorio, formando la ruta relativa para cada archivo en función del rootdirectorio actual , agregando alzipfile contexto que se está ejecutando .

Y la salida se presenta así:

$ python3 zip_cap_dirs.py
Compressing: ./cap_01
Compressing: ./cap_02
Compressing: ./cap_03

Para ver el contenido de cada .zipdirectorio, puede usar el lesscomando:

$ less cap_01.zip

Archive:  cap_01.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
  22017  Defl:N     2471  89% 2019-09-05 08:05 7a3b5ec6  cap_01/0101000001.json
  21998  Defl:N     2471  89% 2019-09-05 08:05 155bece7  cap_01/0101000002.json
  23236  Defl:N     2573  89% 2019-09-05 08:05 55fced20  cap_01/0101000003.json
--------          ------- ---                           -------
  67251             7515  89%                            3 files
ivanleoncz
fuente
0

Aquí hay un enfoque moderno, usando pathlib y un administrador de contexto. Pone los archivos directamente en el zip, en lugar de en una subcarpeta.

def zip_dir(filename: str, dir_to_zip: pathlib.Path):
    with zipfile.ZipFile(filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
        # Use glob instead of iterdir(), to cover all subdirectories.
        for directory in dir_to_zip.glob('**'):
            for file in directory.iterdir():
                if not file.is_file():
                    continue
                # Strip the first component, so we don't create an uneeded subdirectory
                # containing everything.
                zip_path = pathlib.Path(*file.parts[1:])
                # Use a string, since zipfile doesn't support pathlib  directly.
                zipf.write(str(file), str(zip_path))
Las tortugas son lindas
fuente
0

Preparé una función consolidando la solución de Mark Byers con los comentarios de Reimund y Morten Zilmer (ruta relativa e incluyendo directorios vacíos). Como mejor práctica,with se utiliza en la construcción de archivos ZipFile.

La función también prepara un nombre de archivo zip predeterminado con el nombre del directorio comprimido y la extensión '.zip'. Por lo tanto, funciona con un solo argumento: el directorio fuente que se va a comprimir.

import os
import zipfile

def zip_dir(path_dir, path_file_zip=''):
if not path_file_zip:
    path_file_zip = os.path.join(
        os.path.dirname(path_dir), os.path.basename(path_dir)+'.zip')
with zipfile.ZipFile(path_file_zip, 'wb', zipfile.ZIP_DEFLATED) as zip_file:
    for root, dirs, files in os.walk(path_dir):
        for file_or_dir in files + dirs:
            zip_file.write(
                os.path.join(root, file_or_dir),
                os.path.relpath(os.path.join(root, file_or_dir),
                                os.path.join(path_dir, os.path.pardir)))
Gürol Canbek
fuente
0
# import required python modules
# You have to install zipfile package using pip install

import os,zipfile

# Change the directory where you want your new zip file to be

os.chdir('Type your destination')

# Create a new zipfile ( I called it myfile )

zf = zipfile.ZipFile('myfile.zip','w')

# os.walk gives a directory tree. Access the files using a for loop

for dirnames,folders,files in os.walk('Type your directory'):
    zf.write('Type your Directory')
    for file in files:
        zf.write(os.path.join('Type your directory',file))
Praveen
fuente
0

Bueno, después de leer las sugerencias, se me ocurrió una forma muy similar que funciona con 2.7.x sin crear nombres de directorio "divertidos" (nombres absolutos), y solo crearé la carpeta especificada dentro del zip.

O solo en caso de que necesite que su zip contenga una carpeta dentro con el contenido del directorio seleccionado.

def zipDir( path, ziph ) :
 """
 Inserts directory (path) into zipfile instance (ziph)
 """
 for root, dirs, files in os.walk( path ) :
  for file in files :
   ziph.write( os.path.join( root, file ) , os.path.basename( os.path.normpath( path ) ) + "\\" + file )

def makeZip( pathToFolder ) :
 """
 Creates a zip file with the specified folder
 """
 zipf = zipfile.ZipFile( pathToFolder + 'file.zip', 'w', zipfile.ZIP_DEFLATED )
 zipDir( pathToFolder, zipf )
 zipf.close()
 print( "Zip file saved to: " + pathToFolder)

makeZip( "c:\\path\\to\\folder\\to\\insert\\into\\zipfile" )
Xedret
fuente
0

Función para crear archivo zip.

def CREATEZIPFILE(zipname, path):
    #function to create a zip file
    #Parameters: zipname - name of the zip file; path - name of folder/file to be put in zip file

    zipf = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED)
    zipf.setpassword(b"password") #if you want to set password to zipfile

    #checks if the path is file or directory
    if os.path.isdir(path):
        for files in os.listdir(path):
            zipf.write(os.path.join(path, files), files)

    elif os.path.isfile(path):
        zipf.write(os.path.join(path), path)
    zipf.close()
sushh
fuente
explique con un ejemplo para que pueda corregir mi respuesta
sushh
Sin embargo, el archivo zip "actualmente no puede crear un archivo cifrado" (de docs.python.org/3.9/library/zipfile.html )
Georg
0

Usando zipfly

import zipfly

paths = [
    {
        'fs': '/path/to/large/file'
    },
]

zfly = zipfly.ZipFly( paths = paths )

with open("large.zip", "wb") as f:
    for i in zfly.generator():
        f.write(i)
sandes
fuente