zipfile per comprimere e decomprimere file ZIP in Python

Attività commerciale

Il modulo zipfile della libreria standard di Python può essere usato per comprimere file in ZIP e decomprimere file ZIP. È incluso nella libreria standard, quindi non è richiesta alcuna installazione aggiuntiva.

Vengono spiegati i seguenti contenuti.

  • Comprimere più file in un file ZIP
  • Aggiungere un nuovo file a un file ZIP esistente
  • Comprimere una directory (cartella) in un file ZIP
  • Compresso in un file ZIP con una password
  • Controlla il contenuto del file ZIP.
  • Estrarre (scompattare) l'intero contenuto del file ZIP.
  • Selezionate il contenuto del file ZIP ed estraetelo.

Comprimere più file in un file ZIP

Create un oggetto ZipFile e usate il metodo write() per aggiungere i file che volete comprimere.

Per creare un nuovo file ZIP, specificare il percorso del file ZIP da creare come primo argomento del costruttore dell'oggetto ZipFile, e il secondo argomento come segue'w'

Inoltre, il metodo di compressione può essere specificato come terzo argomento.

  • zipfile.ZIP_STORED:Combina semplicemente più file senza compressione (predefinito)
  • zipfile.ZIP_DEFLATED:Compressione ZIP normale (modulo zlib richiesto)
  • zipfile.ZIP_BZIP2:compressione BZIP2 (modulo bz2 richiesto)
  • zipfile.ZIP_LZMA:compressione LZMA (modulo lzma richiesto)

BZIP2 e LZMA hanno un rapporto di compressione più alto (possono essere compressi ad una dimensione minore), ma il tempo richiesto per la compressione è più lungo.

Nel metodo write(), il file con il primo argomento filename viene scritto in un file ZIP con il secondo argomento arcname. Se arcname è omesso, il nome del file viene usato così com'è. arcname può anche specificare una struttura di directory.

L'oggetto ZipFile deve essere chiuso con il metodo close(), ma se usate l'istruzione with, sarà chiuso automaticamente quando il blocco è finito.

import zipfile

with zipfile.ZipFile('data/temp/new_comp.zip', 'w', compression=zipfile.ZIP_DEFLATED) as new_zip:
    new_zip.write('data/temp/test1.txt', arcname='test1.txt')
    new_zip.write('data/temp/test2.txt', arcname='zipdir/test2.txt')
    new_zip.write('data/temp/test3.txt', arcname='zipdir/sub_dir/test3.txt')

Specificando l'argomento compress_type del metodo write(), è anche possibile selezionare il metodo di compressione per ogni file.

with zipfile.ZipFile('data/temp/new_comp_single.zip', 'w') as new_zip:
    new_zip.write('data/temp/test1.txt', arcname='test1.txt', compress_type=zipfile.ZIP_DEFLATED)
    new_zip.write('data/temp/test2.txt', arcname='zipdir/test2.txt')
    new_zip.write('data/temp/test3.txt', arcname='zipdir/sub_dir/test3.txt')

Aggiungere un nuovo file a un file ZIP esistente

Per aggiungere un nuovo file a un file zip esistente, impostate il primo argomento del costruttore sul percorso del file zip esistente quando create l'oggetto ZipFile. Inoltre, imposta il secondo argomento come segue.'a'

Poi, come nell'esempio precedente, basta aggiungere il file usando il metodo write().

with zipfile.ZipFile('data/temp/new_comp.zip', 'a') as existing_zip:
    existing_zip.write('data/temp/test4.txt', arcname='test4.txt')

Comprimere una directory (cartella) in un file ZIP

Se volete comprimere un'intera directory (cartella) in un singolo file ZIP, potete usare os.scandir() o os.listdir() per fare una lista di file, ma è più facile usare make_archive() nel modulo shutil.

Vedere il seguente articolo.

Compresso in un file ZIP con una password

Il modulo zipfile non permette di creare ZIP protetti da password. Se vuoi comprimere un file in un file zip protetto da password, usa la libreria di terze parti pyminizip.

Si noti che la decompressione di ZIP protetti da password può essere fatta con il modulo zipfile (vedi sotto).

Controlla il contenuto del file ZIP.

Puoi controllare il contenuto di un file ZIP esistente.

Crea un oggetto ZipFile impostando il primo argomento file nel costruttore al percorso del file zip esistente e il secondo argomento mode a 'r'. L'argomento mode può essere omesso poiché il default è 'r'.

Potete usare il metodo namelist() dell'oggetto ZipFile per ottenere una lista di file archiviati.

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    print(existing_zip.namelist())
# ['test1.txt', 'zipdir/test2.txt', 'zipdir/sub_dir/test3.txt', 'test4.txt']

Estrarre (scompattare) l'intero contenuto del file ZIP.

Per spacchettare il contenuto di un file ZIP, create un oggetto ZipFile con il primo argomento file nel costruttore come il percorso del file ZIP esistente e il secondo argomento mode come 'r', come nell'esempio sopra. L'argomento mode può essere omesso poiché è predefinito a 'r'.

Il metodo extractall() dell'oggetto ZipFile estrae (decomprime) l'intero contenuto del file ZIP. Il primo argomento, path, specifica il percorso della directory in cui estrarre. Se viene omesso, i file saranno estratti nella directory corrente.

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    existing_zip.extractall('data/temp/ext')

Un file ZIP con una password può essere estratto specificando la password come argomento pwd del metodo extractall().

with zipfile.ZipFile('data/temp/new_comp_with_pass.zip') as pass_zip:
    pass_zip.extractall('data/temp/ext_pass', pwd='password')

Selezionate il contenuto del file ZIP ed estraetelo.

Se volete decomprimere ed estrarre solo alcuni file, usate il metodo extract().

Il primo argomento del metodo extract() è il nome del file da estrarre, e il secondo argomento path è il percorso della directory in cui estrarre. Se l'argomento path viene omesso, il file verrà estratto nella directory corrente. Il nome del file da estrarre dovrebbe includere il percorso della directory nel file ZIP, se è memorizzato lì.

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    existing_zip.extract('test1.txt', 'data/temp/ext2')

Come il metodo extractall(), anche il metodo extract() permette di specificare una password come argomento pwd.

with zipfile.ZipFile('data/temp/new_comp_with_pass.zip') as pass_zip:
    pass_zip.extract('test1.txt', 'data/temp/ext_pass2', pwd='password')