Zip-Archiv aus mehreren Dateien oder einem Verzeichnis erstellen

Pythons zipfile-Modul bietet eine ZipFile-Klasse an, die man verwenden kann, um eine Zip-Archivdatei zu erstellen.
Dazu ist folgender Import notwendig:
from zipfile import ZipFile

Erstellen eines Zip-Archivs aus mehreren Dateien

Man erstellt ein ZipFile-Objekt, und übergibt dabei den Dateinamen sowie den Modus ‚w‘ (Schreibmodus). Es wird eine neue Zip-Datei erstellt und das ZipFile-Objekt geöffnet.
Man ruft die Funktion write() auf dem ZipFile-Objekt auf, um die Dateien darin hinzuzufügen.
Am Ende ruft man die Funktion close() auf, um die Zip-Datei ordnungsgemäß zu schließen.

# ZipFile-Objekt erstellen
zipObj = ZipFile('sample.zip', 'w')
# einzelne Dateien dem Archiv hinzufügen
zipObj.write('sample_file.csv')
zipObj.write('test_1.log')
zipObj.write('test_2.log')
# ZipFile-Objekt schliessen
zipObj.close()

Man kann auch ein with open verwenden, welches automatisch zu einem close führt am Ende der Verarbeitung.

# ZipFile-Objekt erstellen
with ZipFile('sample2.zip', 'w') as zipObj2:
   # einzelne Dateien dem Archiv hinzufügen
   zipObj2.write('sample_file.csv')
   zipObj2.write('test_1.log')
   zipObj2.write('test_2.log')

Zip-Archiv eines Verzeichnisses erstellen

Um den gesamten Inhalt eines Verzeichnisses in ein Zip-Archiv zu packen, müssen alle Dateien im Verzeichnis und seinen Unterverzeichnissen durchlaufen und dann jeder Eintrag mit ZipFile.write() in die Zip-Datei eingefügt werden.

from zipfile import ZipFile
import os
from os.path import basename

with ZipFile('sampleDir.zip', 'w') as zipObj:
   
   for folderName, subfolders, filenames in os.walk(dirName):
       for filename in filenames:
           # der komplette Pfad zur Datei wird erstellt
           filePath = os.path.join(folderName, filename)
           zipObj.write(filePath, basename(filePath))

Anstatt mit os.walk kann die Funktion auch mit Path realisiert werden.

with ZipFile(pathlib.Path(dirname / zip_filename), 'w') as zipfile:
    walk_path = pathlib.Path(dirname)
    for entry in walk_path.glob('**/*'):
        zipfile.write(entry, entry.name)

Ausgewählte Dateien aus einem Verzeichnis anhand von Filtern oder Wildcards zippen

Um ausgewählte Dateien aus einem Verzeichnis zu zippen, muss man die Bedingung für jeden Dateipfad während der Iteration prüfen, bevor man ihn zur Zip-Datei hinzufügt. Nur Dateien, die den Filter bestehen, werden in die Zip-Datei aufgenommen, z.B.

from zipfile import ZipFile
import os
from os.path import basename
# Zip alle Datein aus einem Verzeichnis, die zum Filter passen
def zipFilesInDir(dirName, zipFileName, filter):

   with ZipFile(zipFileName, 'w') as zipObj:
       for folderName, subfolders, filenames in os.walk(dirName):
           for filename in filenames:
               if filter(filename):
                   filePath = os.path.join(folderName, filename)
                   zipObj.write(filePath, basename(filePath))

Um z.B. nur csv-Dateien aus einem Verzeichnis zu zippen, kann man eine Lambda-Funktion als Argument übergeben.
Beispiel für einen Aufruf der Funktion:
zipFilesInDir('sampleDir', 'sampleDir2.zip', lambda name : 'csv' in name)