Corso
Prerequisiti per lavorare con i file Zip
- Devi conoscere la gestione dei file in Python per comprendere la gestione dei file Zip. Se non conosci la gestione dei file, vai alla sezione File Handling di W3Schools per imparare.
- Concetti OOP in Python
- Concetti di Python come condizionali, cicli, funzioni, classi, ecc.
- Se non conosci Python, segui il corso gratuito di DataCamp Intro to Python for Data Science per imparare il linguaggio Python oppure leggi la documentazione ufficiale di Python.
Apri questo link per scaricare tutte le cartelle Zip che ho usato nelle prossime sezioni.
Che cos'è un file Zip?
Zip è un formato di file archivio che supporta la compressione dati senza perdita. Il file Zip è un singolo file che contiene uno o più file compressi.
A cosa servono i file Zip?
- I file Zip ti aiutano a raccogliere tutti i file correlati in un unico posto.
- I file Zip aiutano a ridurre la dimensione dei dati.
- I file Zip si trasferiscono più velocemente rispetto ai singoli file su molte connessioni.
Modulo zipfile
Esplora tutti i metodi e le classi del modulo zipfile usando il metodo dir(). Guarda il codice per ottenere tutte le classi e i metodi del modulo zipfile.
import zipfile # importing the 'zipfile' module
print(dir(zipfile))
['BZIP2_VERSION', 'BadZipFile', 'BadZipfile', 'DEFAULT_VERSION', 'LZMACompressor', 'LZMADecompressor', 'LZMA_VERSION', 'LargeZipFile', 'MAX_EXTRACT_VERSION', 'PyZipFile', 'ZIP64_LIMIT', 'ZIP64_VERSION', 'ZIP_BZIP2', 'ZIP_DEFLATED', 'ZIP_FILECOUNT_LIMIT', 'ZIP_LZMA', 'ZIP_MAX_COMMENT', 'ZIP_STORED', 'ZipExtFile', 'ZipFile', 'ZipInfo', '_CD64_CREATE_VERSION', '_CD64_DIRECTORY_RECSIZE', '_CD64_DIRECTORY_SIZE', '_CD64_DISK_NUMBER', '_CD64_DISK_NUMBER_START', '_CD64_EXTRACT_VERSION', '_CD64_NUMBER_ENTRIES_THIS_DISK', '_CD64_NUMBER_ENTRIES_TOTAL', '_CD64_OFFSET_START_CENTDIR', '_CD64_SIGNATURE', '_CD_COMMENT_LENGTH', '_CD_COMPRESSED_SIZE', '_CD_COMPRESS_TYPE', '_CD_CRC', '_CD_CREATE_SYSTEM', '_CD_CREATE_VERSION', '_CD_DATE', '_CD_DISK_NUMBER_START', '_CD_EXTERNAL_FILE_ATTRIBUTES', '_CD_EXTRACT_SYSTEM', '_CD_EXTRACT_VERSION', '_CD_EXTRA_FIELD_LENGTH', '_CD_FILENAME_LENGTH', '_CD_FLAG_BITS', '_CD_INTERNAL_FILE_ATTRIBUTES', '_CD_LOCAL_HEADER_OFFSET', '_CD_SIGNATURE', '_CD_TIME', '_CD_UNCOMPRESSED_SIZE', '_ECD_COMMENT', '_ECD_COMMENT_SIZE', '_ECD_DISK_NUMBER', '_ECD_DISK_START', '_ECD_ENTRIES_THIS_DISK', '_ECD_ENTRIES_TOTAL', '_ECD_LOCATION', '_ECD_OFFSET', '_ECD_SIGNATURE', '_ECD_SIZE', '_EndRecData', '_EndRecData64', '_FH_COMPRESSED_SIZE', '_FH_COMPRESSION_METHOD', '_FH_CRC', '_FH_EXTRACT_SYSTEM', '_FH_EXTRACT_VERSION', '_FH_EXTRA_FIELD_LENGTH', '_FH_FILENAME_LENGTH', '_FH_GENERAL_PURPOSE_FLAG_BITS', '_FH_LAST_MOD_DATE', '_FH_LAST_MOD_TIME', '_FH_SIGNATURE', '_FH_UNCOMPRESSED_SIZE', '_SharedFile', '_Tellable', '_ZipDecrypter', '_ZipWriteFile', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_check_compression', '_check_zipfile', '_get_compressor', '_get_decompressor', 'binascii', 'bz2', 'compressor_names', 'crc32', 'error', 'importlib', 'io', 'is_zipfile', 'lzma', 'main', 'os', 're', 'shutil', 'sizeCentralDir', 'sizeEndCentDir', 'sizeEndCentDir64', 'sizeEndCentDir64Locator', 'sizeFileHeader', 'stat', 'stringCentralDir', 'stringEndArchive', 'stringEndArchive64', 'stringEndArchive64Locator', 'stringFileHeader', 'struct', 'structCentralDir', 'structEndArchive', 'structEndArchive64', 'structEndArchive64Locator', 'structFileHeader', 'sys', 'threading', 'time', 'zlib']
Hai visto un mucchio di classi e metodi, giusto? Ma non li imparerai tutti. Imparerai solo alcune classi e alcuni metodi per lavorare con i file Zip.
Vediamo alcune eccezioni, classi e metodi utili con brevi spiegazioni.
Eccezioni
Un'eccezione è un messaggio usato per mostrare l'errore esatto come preferisci. In Python usi le parole chiave try, except, finally per la gestione degli errori.
Se non hai familiarità con la gestione degli errori, vai alla documentazione su Error Handling di Python per impararla.
Vediamo tutte le eccezioni nel modulo zipfile.
zipfile.BadZipFile
zipfile.BadZipFile è un'eccezione del modulo zipfile. Questo errore viene sollevato per i file Zip danneggiati. Vedi l'esempio qui sotto.
## zipfile.BadZipFile
import zipfile
def main():
try:
with zipfile.ZipFile('sample_file.zip') as file: # opening the zip file using 'zipfile.ZipFile' class
print("Ok")
except zipfile.BadZipFile: # if the zip file has any errors then it prints the error message which you wrote under the 'except' block
print('Error: Zip file is corrupted')
if __name__ == '__main__': main()
## I used a badfile for the test
Ok
zipfile.LargeZipFile
Supponi di voler lavorare con un file Zip di grandi dimensioni: devi abilitare la funzionalità ZIP64 quando apri lo Zip. Se non la abiliti, verrà sollevata LargeZipFile. Ecco un esempio.
## zipfile.LargeZipFile
## Without enabling 'Zip64'
import zipfile
def main():
try:
with zipfile.ZipFile('sample_file.zip') as file:
print('File size is compatible')
except zipfile.LargeZipFile: # it raises an 'LargeZipFile' error because you didn't enable the 'Zip64'
print('Error: File size if too large')
if __name__ == '__main__': main()
File size is compatible
## zipfile.LargeZipFile
## With enabling 'ZIP64'
import zipfile
def main():
try:
with zipfile.ZipFile('sample_file.zip', mode = 'r', allowZip64 = True) as file: # here enabling the 'Zip64'
print('File size is compatible')
except zipfile.LargeZipFile:
print('Error: File size if too large') # if the file size is too large to open it prints the error you have written
if __name__ == '__main__': main()
File size is compatible
Scegli un file Zip adatto per la gestione delle eccezioni e prova a eseguire il programma. Ti sarà tutto più chiaro.
Classi
In parole semplici, una classe è un insieme di metodi e attributi. Usi i metodi e gli attributi della classe ovunque ti servano creando le istanze della classe.
Vediamo alcune classi del modulo zipfile.
zipfile.ZipFile
La classe più comune per lavorare con i file Zip è la classe ZipFile.
zipfile.ZipFile è usata per scrivere e leggere i file Zip. Include alcuni metodi utili per gestire i file Zip.
Ora esplora i metodi della classe ZipFile usando gli oggetti dir(). Vedi il codice.
import zipfile
print(dir(zipfile.ZipFile)) # accessing the 'ZipFile' class
['_RealGetContents', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_extract_member', '_fpclose', '_open_to_write', '_sanitize_windows_name', '_windows_illegal_name_trans_table', '_write_end_record', '_writecheck', 'close', 'comment', 'extract', 'extractall', 'fp', 'getinfo', 'infolist', 'namelist', 'open', 'printdir', 'read', 'setpassword', 'testzip', 'write', 'writestr']
Hai già usato la classe zipfile.ZipFile per leggere i file Zip negli esempi precedenti.
zipfile.ZipFile contiene molti metodi come extract, open, getinfo, setpassword, ecc., per lavorare con i file Zip.
Vediamo alcuni metodi della classe ZipFile.
## zipfile.ZipFile
import zipfile
def main():
with zipfile.ZipFile('sample_file.zip') as file:
# ZipFile.infolist() returns a list containing all the members of an archive file
print(file.infolist())
# ZipFile.namelist() returns a list containing all the members with names of an archive file
print(file.namelist())
# ZipFile.getinfo(path = filepath) returns the information about a member of Zip file.
# It raises a KeyError if it doesn't contain the mentioned file
print(file.getinfo(file.namelist()[-1]))
# ZipFile.open(path = filepath, mode = mode_type, pwd = password) opens the members of an archive file
# 'pwd' is optional -> if it has password mention otherwise leave it
text_file = file.open(name = file.namelist()[-1], mode = 'r')
# 'read()' method of the file prints all the content of the file. You see this method in file handling.
print(text_file.read())
# You must close the file if you don't open a file using 'with' keyword
# 'close()' method is used to close the file
text_file.close()
# ZipFile.extractall(path = filepath, pwd = password) extracts all the files to current directory
file.extractall()
# after executing check the directory to see extracted files
if __name__ == '__main__': main()
[<ZipInfo filename='extra_file.txt' filemode='-rw-rw-rw-' file_size=59>, <ZipInfo filename='READ ME.txt' filemode='-rw-rw-rw-' file_size=59>, <ZipInfo filename='even_odd.py' filemode='-rw-rw-rw-' file_size=129>]
['extra_file.txt', 'READ ME.txt', 'even_odd.py']
<ZipInfo filename='even_odd.py' filemode='-rw-rw-rw-' file_size=129>
b"num = int(input('Enter a Number:- '))\r\nif num % 2 == 0:\r\n\tprint('{} is Even'.fromat(num))\r\nelse:\r\n\tprint('{} is Odd'.fromat(num))"
Se vuoi imparare tutti i metodi della classe ZipFile, usa la funzione help() sul metodo che vuoi approfondire.
Oppure vai alla documentazione ufficiale di Python per imparare.
zipfile.ZipInfo
La classe zipfile.ZipInfo è usata per rappresentare un elemento di una cartella Zip.
Per prima cosa, esplora tutti gli oggetti della classe zipfile.ZipInfo usando il metodo dir(). Vedi il codice qui sotto.
## zipfile.ZipInfo
import zipfile
print(dir(zipfile.ZipInfo))
['CRC', 'FileHeader', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '_decodeExtra', '_encodeFilenameFlags', '_raw_time', 'comment', 'compress_size', 'compress_type', 'create_system', 'create_version', 'date_time', 'external_attr', 'extra', 'extract_version', 'file_size', 'filename', 'flag_bits', 'from_file', 'header_offset', 'internal_attr', 'is_dir', 'orig_filename', 'reserved', 'volume']
Ora vedrai alcuni metodi della classe zipfile.ZipInfo
## zipfile.ZipInfo
import zipfile
def main():
with zipfile.ZipFile('sample_file.zip') as file:
# 'infolist()' is the object of 'ZipFile' class
# 'infolist()' returns a list containing all the folders and files of the zip -> 'ZipInfo' objects
# assigning last element of the list to a variable to test all the methods of 'ZipInfo'
archive = file.infolist()
read_me_file = archive[-1]
# 'ZipInfo' methods
# ZipInfo_object.filename returns the name of the file
print("Name of the file:- {}".format(read_me_file.filename))
# ZipInfo_object.file_size returns the size of the file
print("Size of the file:- {}".format(read_me_file.file_size))
# ZipInfo_object.is_dir() returns True if it's directory otherwise False
print("Is directory:- {}".format(read_me_file.is_dir()))
# ZipInfo_object.date_time() returns the created date & time of file
print("File created data & time:- {}".format(read_me_file.date_time))
if __name__ == '__main__': main()
Name of the file:- sample_file/READ ME.txt
Size of the file:- 59
Is directory:- False
File created data & time:- (2018, 10, 4, 11, 32, 22)
Vai a ZipInfo se vuoi imparare di più sugli oggetti di ZipInfo.
Metodi
I metodi sono blocchi di codice dedicati a una funzionalità specifica nel programma. Per esempio, se vuoi trovare il valore assoluto di un numero, puoi usare il metodo di Python chiamato abs.
Puoi usarli ovunque ti serva. Vediamo alcuni metodi del modulo zipfile.
zipfile.is_zipfile()
Il metodo is_zipfile(filename) del modulo zipfile restituisce True se il file è uno Zip valido, altrimenti restituisce False.
Vediamo un esempio.
## zipfile.is_zip(filename)
import zipfile
def main():
print(zipfile.is_zipfile('sample_file.zip')) # it returns True
if __name__ == '__main__': main()
True
Gestire i file Zip
In questa sezione imparerai a gestire i file Zip come apertura, estrazione, scrittura, ecc.
Estrarre un file Zip
Estrai i file di un Zip usando il metodo extractall nella directory corrente.
## extracting zip file
import zipfile
def main():
# assigning filename to a variable
file_name = 'sample_file.zip'
# opening Zip using 'with' keyword in read mode
with zipfile.ZipFile(file_name, 'r') as file:
# printing all the information of archive file contents using 'printdir' method
print(file.printdir())
# extracting the files using 'extracall' method
print('Extracting all files...')
file.extractall()
print('Done!') # check your directory of zip file to see the extracted files
if __name__ == '__main__': main()
File Name Modified Size
sample_file/ 2018-10-04 11:33:22 0
sample_file/even_odd.py 2018-06-29 23:35:54 129
sample_file/READ ME.txt 2018-10-04 11:32:22 59
None
Extracting all files...
Done!
Estrarre uno Zip con password
Per estrarre uno Zip con password, devi passare un valore all'argomento posizionale pwd dei metodi extract(pwd = password) o extractall(pwd = password).
Devi passare una password in formato bytes. Per convertire una str in bytes usa il metodo integrato di Python bytes con codifica utf-8.
Vediamo un esempio.
## extracting zip with password
import zipfile
def main():
file_name = 'pswd_file.zip'
pswd = 'datacamp'
with zipfile.ZipFile(file_name) as file:
# password you pass must be in the bytes you converted 'str' into 'bytes'
file.extractall(pwd = bytes(pswd, 'utf-8'))
if __name__ == '__main__': main()
Puoi anche estrarre i file usando il metodo setpassword(pwd = password) della classe ZipFile. Vedi l'esempio qui sotto.
## extracting zip with password
import zipfile
def main():
file_name = 'pswd_file.zip'
pswd = 'datacamp'
with zipfile.ZipFile(file_name) as file:
# 'setpassword' method is used to give a password to the 'Zip'
file.setpassword(pwd = bytes(pswd, 'utf-8'))
file.extractall()
if __name__ == '__main__': main()
Creare file Zip
Per creare un file Zip non ti servono metodi extra. Passa semplicemente il nome alla classe ZipFile e verrà creato un archivio nella directory corrente.
Guarda l'esempio qui sotto.
## Creating Zip file
import zipfile
def main():
archive_name = 'example_file.zip'
# below one line of code will create a 'Zip' in the current working directory
with zipfile.ZipFile(archive_name, 'w') as file:
print("{} is created.".format(archive_name))
if __name__ == '__main__': main()
example_file.zip is created.
Scrivere nei file Zip
Devi aprire i file Zip in modalità scrittura per scrivere file nell'archivio. Questa modalità sovrascrive tutti i file esistenti nello Zip.
Vediamo un esempio.
## Writing files to zip
import zipfile
def main():
file_name = 'sample_file.zip'
# Opening the 'Zip' in writing mode
with zipfile.ZipFile(file_name, 'w') as file:
# write mode overrides all the existing files in the 'Zip.'
# you have to create the file which you have to write to the 'Zip.'
file.write('extra_file.txt')
print('File overrides the existing files')
# opening the 'Zip' in reading mode to check
with zipfile.ZipFile(file_name, 'r') as file:
print(file.namelist())
if __name__ == '__main__': main()
File overrides the existing files
['extra_file.txt']
Aggiungere file a uno Zip
Devi aprire lo Zip in modalità append (a) per aggiungere file allo Zip. Non sovrascrive i file esistenti.
Vediamo un esempio.
## Appending files to zip
import zipfile
def main():
file_name = 'sample_file.zip'
# opening the 'Zip' in writing mode
with zipfile.ZipFile(file_name, 'a') as file:
# append mode adds files to the 'Zip'
# you have to create the files which you have to add to the 'Zip'
file.write('READ ME.txt')
file.write('even_odd.py')
print('Files added to the Zip')
# opening the 'Zip' in reading mode to check
with zipfile.ZipFile(file_name, 'r') as file:
print(file.namelist())
if __name__ == '__main__': main()
Files added to the Zip ['extra_file.txt', 'READ ME.txt', 'even_odd.py']Finora hai imparato a gestire i file Zip. Ora sei in grado di aprire, scrivere, aggiungere, estrarre, creare, ecc., file Zip. Adesso scriverai un semplice programma.
Vediamo di cosa si tratta.
Estrarre più sotto-zip con password usando cicli e zipfile
- Hai uno Zip che contiene alcuni sotto-file Zip annidati. E ognuno dei file Zip ha una password che corrisponde al proprio nome. La nostra sfida è decomprimere tutti gli Zip fino ad arrivare alla fine.
Passi per risolvere il problema
- Estrai il file padre usando il suo nome come password.
- Ottieni il nome del primo figlio usando il metodo namelist(). Salvalo in una variabile.
-
Esegui il ciclo per un numero infinito di volte.
-
Verifica se il file è uno Zip usando il metodo is_zipfile(). Se sì, fai quanto segue.
-
Apri lo zip con la variabile name.
-
Ricava la password dello Zip dalla variabile name.
-
Estrai lo Zip.
-
Ottieni e memorizza il nome del prossimo Zip nella variabile name.
-
-
altrimenti
- Interrompi il ciclo usando break.
-
Ho creato la procedura qui sopra. Se vuoi puoi adattarla in base alla disposizione dei tuoi file.
## Solution
import zipfile
def main():
# storing the parent name
parent_file_name = '000.zip'
with zipfile.ZipFile(parent_file_name, 'r') as parent_file:
# extracting the parent file
pswd = bytes(parent_file_name.split('.')[0], 'utf-8')
parent_file.extractall(pwd = pswd)
# getting the first child
next_zip_name = parent_file.namelist()[0]
# looping through the sub zips infinite times until you don't encouter a 'Zip' file
while True:
if zipfile.is_zipfile(next_zip_name):
# opening the zip
with zipfile.ZipFile(next_zip_name, 'r') as child_file:
# getting password from the zip name
pswd = bytes(next_zip_name.split('.')[0], 'utf-8')
# extracting the zip
child_file.extractall(pwd = pswd)
# getting the child zip name
next_zip_name = child_file.namelist()[0]
else:
break
if __name__ == '__main__': main()
Dopo aver eseguito il programma qui sopra, vedrai che tutti i sotto-zip sono stati estratti nella directory corrente.
Nota finale
Congratulazioni per aver completato il tutorial!
Speriamo che il tutorial ti sia piaciuto. Questo articolo ti sarà molto utile quando lavori con i file Zip. Adesso sei in grado di lavorare con i file Zip.
Se hai dubbi sull'articolo, scrivimi nella sezione dei commenti. Risponderò il prima possibile.
Ancora, se sei alle prime armi con Python segui il corso gratuito di DataCamp Intro to Python for Data Science per imparare il linguaggio Python oppure leggi la documentazione ufficiale di Python.
Buon coding!

