27. Leggere e scrivere file
Finora, tutti i dati nei nostri programmi sono stati temporanei—memorizzati in variabili che scompaiono quando il programma termina. Per creare programmi che ricordino informazioni tra un’esecuzione e l’altra, dobbiamo lavorare con i file. I file ci permettono di salvare dati su disco e rileggerli in seguito, abilitando qualsiasi cosa, dalle impostazioni di configurazione all’archiviazione dei dati utente.
In questo capitolo, imparerai come leggere e scrivere su file di testo in Python. Inizieremo comprendendo i percorsi dei file e come Python li individua, poi passeremo ad aprire, leggere, scrivere e chiudere correttamente i file. Imparerai le diverse modalità dei file, la codifica del testo e come gestire gli errori comuni che si verificano durante le operazioni sui file.
27.1) Percorsi dei file e directory di lavoro corrente
Prima di poter lavorare con i file, dobbiamo capire come Python li individua nel file system del tuo computer.
27.1.1) Comprendere i percorsi dei file
Un percorso del file è l’indirizzo di un file sul tuo computer. Dice a Python esattamente dove trovare un file. Esistono due tipi di percorsi:
I percorsi assoluti specificano la posizione completa a partire dalla radice del file system:
- Windows:
C:\Users\Alice\Documents\data.txt - macOS/Linux:
/home/alice/documents/data.txt
I percorsi relativi specificano una posizione relativa alla directory di lavoro corrente:
data.txt(file nella directory corrente)reports/sales.txt(file in una sottodirectory)../config.txt(file nella directory padre)
La directory di lavoro corrente (CWD, current working directory) è la cartella in cui Python cerca i file quando usi percorsi relativi. Quando esegui uno script Python, la CWD è la directory da cui hai lanciato il comando, non necessariamente quella in cui si trova il file dello script.
Per esempio:
# Directory structure:
/home/alice/
└── projects/
└── script.py
# Running from the projects folder:
$ cd /home/alice/projects
$ python script.py
# CWD is /home/alice/projects
# Running from the parent folder:
$ cd /home/alice
$ python projects/script.py
# CWD is /home/alice (not where script.py is!)Puoi verificare la directory di lavoro corrente con:
import os
# Ottieni la directory di lavoro corrente
current_dir = os.getcwd()
print(f"Current directory: {current_dir}")Output:
Current directory: /home/alice/projects/file_demoLa funzione os.getcwd() restituisce il percorso assoluto della directory di lavoro corrente. Questo è utile per capire dove Python cercherà i file quando usi percorsi relativi.
Comprendere la directory di lavoro corrente è importante perché determina dove Python cercherà quando usi un percorso relativo come "data.txt". Se esegui il tuo script da /home/alice/projects/ e apri "data.txt", Python cerca /home/alice/projects/data.txt.
27.1.2) Usare efficacemente i percorsi relativi
Quando lavori con i file, i percorsi relativi sono spesso più comodi dei percorsi assoluti perché rendono il codice portabile—funziona indipendentemente da dove si trova la cartella del progetto su computer diversi.
Ecco schemi comuni di percorsi relativi:
# File nella directory di lavoro corrente
filename = "student_grades.txt"
# File in una sottodirectory (cartella data all'interno della directory corrente)
filename = "data/student_grades.txt"
# File nella directory padre
filename = "../shared_data.txt"Per gli esempi di questo capitolo, useremo principalmente nomi di file semplici come "data.txt". Questo significa:
- I file di dati devono trovarsi nella stessa directory da cui esegui il comando Python
- Se il tuo script è in
/home/alice/projects/e eseguipython script.pyda quella directory, Python cercheràdata.txtin/home/alice/projects/
Questo approccio mantiene gli esempi chiari e focalizzati sulle operazioni sui file, piuttosto che sulla navigazione dei percorsi. Se ottieni un FileNotFoundError, usa os.getcwd() per controllare dove Python sta cercando i file.
27.1.3) Separatori di percorso tra sistemi operativi
Sistemi operativi diversi usano caratteri diversi per separare le directory nei percorsi:
- Windows usa le barre rovesciate:
data\reports\sales.txt - macOS e Linux usano le barre:
data/reports/sales.txt
Python gestisce automaticamente questo aspetto quando usi le barre nel tuo codice—funzionano su tutti i sistemi operativi:
# Questo funziona su Windows, macOS e Linux
filename = "data/reports/sales.txt"Python converte le barre nel separatore appropriato per il tuo sistema operativo.
27.2) Aprire e chiudere i file
Per lavorare con un file, dobbiamo prima aprirlo, creando una connessione tra il nostro programma e il file su disco. Quando abbiamo finito, dobbiamo chiuderlo per rilasciare le risorse di sistema e assicurarci che tutti i dati vengano salvati correttamente.
27.2.1) La funzione open()
La funzione open() crea un oggetto file (file object) che rappresenta la connessione a un file. Nella sua forma più semplice, fornisci il nome del file:
# Apri un file in lettura (modalità predefinita)
file = open("message.txt")Questo apre il file message.txt nella directory corrente. La funzione open() restituisce un oggetto file, che memorizziamo nella variabile file. Questo oggetto fornisce metodi per leggere o scrivere sul file.
Tuttavia, questo approccio di base ha un problema critico: se si verifica un errore dopo l’apertura del file, il file potrebbe non essere mai chiuso. Vediamo perché chiudere i file è importante.
27.2.2) Perché è importante chiudere i file
Quando apri un file, il sistema operativo alloca risorse per mantenere quella connessione. Se non chiudi il file:
- I dati potrebbero non essere salvati: quando scrivi su file, i dati vengono spesso bufferizzati in memoria e scritti su disco solo quando il file viene chiuso
- Le risorse di sistema vengono sprecate: ogni file aperto consuma memoria e handle di file
- Altri programmi potrebbero essere bloccati: alcuni sistemi impediscono ad altri programmi di accedere a un file già aperto
Per chiudere un file, chiama il suo metodo close():
file = open("message.txt")
# ... lavora con il file ...
file.close() # Rilascia le risorse e assicura che i dati siano salvati27.2.3) Il problema della chiusura manuale
Chiudere i file manualmente è soggetto a errori. Se un’eccezione si verifica tra l’apertura e la chiusura, la chiamata a close() potrebbe non essere mai eseguita:
file = open("data.txt")
result = process_data(file) # Se questo solleva un'eccezione...
file.close() # ...questo non viene mai eseguito!Questo è un problema così comune che Python offre una soluzione migliore: l’istruzione with, di cui parleremo nella Sezione 27.4. Per ora, comprendi che aprire e chiudere i file manualmente richiede attenzione per garantire che close() venga sempre chiamato.
27.2.4) Verificare se un file è aperto
Un oggetto file ha un attributo closed che indica se il file è chiuso:
file = open("data.txt")
print(file.closed) # Output: False
file.close()
print(file.closed) # Output: TrueUna volta che un file è chiuso, tentare di leggerlo o scriverci solleverà un errore:
file = open("data.txt")
file.close()
# This raises ValueError: I/O operation on closed file
content = file.read()Il messaggio di errore indica chiaramente il problema: stai cercando di eseguire un’operazione di I/O (input/output) su un file che è già chiuso.
27.3) Comprendere le modalità dei file (r, w, a, testo vs binario) e la codifica
Quando apri un file, puoi specificare una modalità (mode) che determina quali operazioni sono consentite e come il file viene trattato. Comprendere le modalità è fondamentale per lavorare correttamente con i file.
27.3.1) Modalità testo vs modalità binaria
I file possono essere aperti in due modalità fondamentali:
La modalità testo (predefinita) tratta il file come contenente testo. Python automaticamente:
- Converte i terminatori di riga in
\nindipendentemente dalla piattaforma - Gestisce la codifica del testo (convertendo tra byte e stringhe)
- Consente di leggere e scrivere stringhe
La modalità binaria tratta il file come byte grezzi. Python:
- Legge e scrive oggetti bytes, non stringhe
- Non effettua conversioni o interpretazioni
- Si usa per immagini, audio, video e altri file non di testo
Per questo capitolo, ci concentreremo sulla modalità testo, che è quella che userai più spesso. La modalità binaria è indicata aggiungendo 'b' alla stringa della modalità (come 'rb' o 'wb'), ma non ne avremo bisogno per i file di testo.
27.3.2) Le tre modalità principali dei file
Python fornisce tre modalità principali per aprire file di testo:
Modalità lettura ('r') - Apre un file solo in lettura:
file = open("data.txt", "r") # or just open("data.txt")- Il file deve già esistere, altrimenti Python solleva
FileNotFoundError - Puoi leggere dal file ma non puoi scriverci
- È la modalità predefinita se non ne specifichi una
Modalità scrittura ('w') - Apre un file in scrittura:
file = open("output.txt", "w")- Crea il file se non esiste
- Cancella tutto il contenuto esistente se il file esiste già
- Puoi scrivere nel file ma non puoi leggerlo
- Usala quando vuoi creare un nuovo file o sostituire completamente uno esistente
Modalità append ('a') - Apre un file in append:
file = open("log.txt", "a")- Crea il file se non esiste
- Preserva il contenuto esistente e aggiunge nuovo contenuto alla fine
- Puoi scrivere nel file ma non puoi leggerlo
- Usala quando vuoi aggiungere a un file esistente senza perdere il contenuto attuale
Ecco un confronto di come queste modalità influenzano un file esistente:
# Supponiamo che data.txt contenga: "Hello\nWorld\n"
# Modalità lettura - contenuto invariato
file = open("data.txt", "r")
file.close()
# Il file contiene ancora: "Hello\nWorld\n"
# Modalità scrittura - contenuto cancellato
file = open("data.txt", "w")
file.write("New content\n")
file.close()
# Il file ora contiene: "New content\n"
# Modalità append - contenuto preservato, nuovo contenuto aggiunto
file = open("data.txt", "a")
file.write("Added line\n")
file.close()
# Il file ora contiene: "New content\nAdded line\n"27.3.3) Comprendere la codifica del testo
Quando lavori con file di testo, Python deve sapere come convertire tra i byte memorizzati su disco e i caratteri della stringa nel tuo programma. Questo processo di conversione si chiama codifica (encoding).
La codifica più comune è UTF-8, che può rappresentare qualsiasi carattere di qualsiasi lingua. È la codifica predefinita in Python 3 e lo standard per i moderni file di testo.
# Specifica esplicitamente la codifica UTF-8 (anche se di solito è la predefinita)
file = open("data.txt", "r", encoding="utf-8")Perché la codifica è importante? Considera questo file di testo contenente un nome con un carattere accentato:
# Scrivere un file con caratteri speciali
file = open("names.txt", "w", encoding="utf-8")
file.write("José\n")
file.write("François\n")
file.write("Müller\n")
file.close()
# Rileggerlo
file = open("names.txt", "r", encoding="utf-8")
content = file.read()
file.close()
print(content)Output:
José
François
MüllerSe provi ad aprire un file con la codifica sbagliata, potresti vedere caratteri distorti oppure ottenere un errore. Usa sempre UTF-8 per i nuovi file, a meno che tu non abbia un motivo specifico per usare una codifica diversa.
27.3.4) Variazioni aggiuntive della modalità
Python fornisce caratteri di modalità aggiuntivi che possono essere combinati con le modalità principali:
Le modalità plus consentono sia lettura sia scrittura:
'r+'- Lettura e scrittura (il file deve esistere)'w+'- Scrittura e lettura (cancella il contenuto esistente)'a+'- Append e lettura (preserva il contenuto esistente)
Per i principianti, è più chiaro aprire un file una volta per la lettura e separatamente per la scrittura, invece di usare le modalità plus. In questo capitolo rimarremo sulle modalità semplici ('r', 'w', 'a').
27.4) Usare with per gestire automaticamente i file
L’istruzione with fornisce un modo più pulito e sicuro per lavorare con i file. Chiude automaticamente il file quando hai finito, anche se si verifica un errore.
27.4.1) Sintassi dell’istruzione with
Ecco come usare with per aprire un file:
with open("data.txt", "r") as file:
content = file.read()
print(content)
# Il file viene chiuso automaticamente quiLa sintassi ha diverse parti:
with- Keyword che avvia il context manageropen("data.txt", "r")- Apre il fileas file- Crea una variabile per referenziare l’oggetto file:- Inizia il blocco indentato- Blocco indentato - Codice che lavora con il file
- Dopo il blocco - Il file viene chiuso automaticamente
Il vantaggio chiave: Python garantisce che il file verrà chiuso quando il blocco with termina, indipendentemente da come termina (normalmente, con un return o a causa di un’eccezione).
27.4.2) Perché with è migliore della chiusura manuale
Confronta questi due approcci:
# Chiusura manuale - rischiosa
file = open("data.txt", "r")
content = file.read()
result = process(content) # Se questo solleva un'eccezione...
file.close() # ...questo non viene eseguito
# Uso di with - sicuro
with open("data.txt", "r") as file:
content = file.read()
result = process(content) # Anche se questo solleva un'eccezione...
# ...il file viene comunque chiuso automaticamenteL’istruzione with usa il protocollo dei context manager (context manager protocol) di Python (che esploreremo in dettaglio nel Capitolo 28). Per ora, pensalo come una garanzia: "Ripulirò questa risorsa quando hai finito, qualunque cosa accada."
27.4.3) Lavorare con più file
Puoi aprire più file in un’unica istruzione with:
with open("input.txt", "r") as infile, open("output.txt", "w") as outfile:
content = infile.read()
outfile.write(content.upper())
# Entrambi i file vengono chiusi automaticamente quiQuesto è utile quando devi leggere da un file e scrivere su un altro simultaneamente. Entrambi i file sono garantiti come chiusi correttamente, anche se si verifica un errore.
27.4.4) L’oggetto file è valido solo all’interno del blocco with
Una volta che il blocco with termina, il file è chiuso e non puoi più usare l’oggetto file:
with open("data.txt", "r") as file:
content = file.read()
print("Inside with block:", file.closed) # Output: Inside with block: False
print("Outside with block:", file.closed) # Output: Outside with block: True
# This raises ValueError: I/O operation on closed file
more_content = file.read()Questo comportamento è intenzionale—impedisce che tu usi accidentalmente un file chiuso. Se ti serve il contenuto del file al di fuori del blocco with, salvalo in una variabile (come content sopra) prima che il blocco termini.
Da questo punto in avanti nel capitolo, useremo with per tutte le operazioni sui file. È l’approccio raccomandato e quello che dovresti usare nel tuo codice.
27.5) Leggere file di testo
Ora che sappiamo come aprire i file in sicurezza con with, esploriamo i diversi modi per leggere contenuti da file di testo.
27.5.1) Leggere l’intero file con read()
Il metodo read() legge l’intero contenuto del file come un’unica stringa:
with open("message.txt", "r") as file:
content = file.read()
print(content)Se message.txt contiene:
Welcome to Python!
This is a text file.
It has multiple lines.Output:
Welcome to Python!
This is a text file.
It has multiple lines.Il metodo read() include tutti i caratteri di nuova riga (\n) presenti nel file. Quando stampi la stringa, Python visualizza ogni riga su una riga separata proprio grazie a questi caratteri di nuova riga.
Puoi anche leggere un numero specifico di caratteri passando un numero a read():
with open("message.txt", "r") as file:
first_ten = file.read(10) # Leggi i primi 10 caratteri
print(f"First 10 characters: '{first_ten}'")Output:
First 10 characters: 'Welcome to'Leggere l’intero file è semplice e funziona bene per file piccoli. Tuttavia, per file grandi (megabyte o gigabyte), leggere tutto in una volta può consumare troppa memoria. In questi casi, leggere riga per riga è più efficiente.
27.5.2) Leggere riga per riga con readline()
Il metodo readline() legge una singola riga dal file, includendo il carattere di nuova riga alla fine:
with open("message.txt", "r") as file:
line1 = file.readline()
line2 = file.readline()
line3 = file.readline()
print(f"Line 1: {line1}")
print(f"Line 2: {line2}")
print(f"Line 3: {line3}")Output:
Line 1: Welcome to Python!
Line 2: This is a text file.
Line 3: It has multiple lines.
Nota le righe vuote extra nell’output. Ogni riga letta dal file termina con \n, e print() aggiunge un’altra nuova riga. Per evitarlo, usa il metodo rstrip() per rimuovere gli spazi bianchi finali:
with open("message.txt", "r") as file:
line1 = file.readline().rstrip()
line2 = file.readline().rstrip()
print(f"Line 1: {line1}")
print(f"Line 2: {line2}")Output:
Line 1: Welcome to Python!
Line 2: This is a text file.Quando readline() raggiunge la fine del file, restituisce una stringa vuota "". Questo ti permette di rilevare quando non ci sono più righe da leggere:
with open("message.txt", "r") as file:
while True:
line = file.readline()
if line == "": # Fine del file
break
print(line.rstrip())Tuttavia, esiste un modo più Pythonic per leggere i file riga per riga.
27.5.3) Iterare sulle righe con un ciclo for
Gli oggetti file sono iterabili (iterable), il che significa che puoi fare un ciclo direttamente su di essi con un ciclo for. Questo è il modo più comune e più Pythonic per leggere un file riga per riga:
with open("message.txt", "r") as file:
for line in file:
print(line.rstrip())Output:
Welcome to Python!
This is a text file.
It has multiple lines.Questo approccio è:
- Più pulito: non c’è bisogno di
readline()o di controllare stringhe vuote - Più efficiente: Python legge il file a blocchi, senza caricare l’intero file in memoria
- Più Pythonic: usa l’iterazione, che è un concetto fondamentale di Python
Ogni iterazione del ciclo legge la riga successiva dal file. Quando non ci sono più righe, il ciclo termina automaticamente.
27.5.4) Leggere tutte le righe in una lista con readlines()
Il metodo readlines() legge tutte le righe dal file e le restituisce come una lista(list) di stringhe:
with open("message.txt", "r") as file:
lines = file.readlines()
print(f"Number of lines: {len(lines)}")
for i, line in enumerate(lines, start=1):
print(f"Line {i}: {line.rstrip()}")Output:
Number of lines: 3
Line 1: Welcome to Python!
Line 2: This is a text file.
Line 3: It has multiple lines.Ogni elemento della lista è una stringa contenente una riga del file, incluso il suo carattere di nuova riga. Questo è utile quando hai bisogno di:
- Accedere alle righe per indice:
lines[0],lines[1], ecc. - Elaborare le righe più volte
- Conoscere il numero totale di righe prima dell’elaborazione
Tuttavia, come read(), readlines() carica l’intero file in memoria. Per file grandi, iterare con un ciclo for è più efficiente in termini di memoria.
27.6) Scrivere e aggiungere contenuto a file di testo
Scrivere sui file è importante quanto leggerli. Python offre metodi semplici per creare nuovi file o modificare quelli esistenti.
27.6.1) Scrivere su un file con write()
Per scrivere su un file, aprilo in modalità scrittura ('w') e usa il metodo write():
with open("output.txt", "w") as file:
file.write("Hello, World!\n")
file.write("This is a new file.\n")Dopo aver eseguito questo codice, output.txt contiene:
Hello, World!
This is a new file.Punti importanti su write():
- Scrive una stringa nel file
- Non aggiunge automaticamente caratteri di nuova riga—devi includere
\ntu stesso - Restituisce il numero di caratteri scritti (anche se di solito lo ignoriamo)
- Se il file esiste già, la modalità scrittura cancella tutto il contenuto esistente prima di scrivere
Vediamo cosa succede quando scriviamo su un file esistente:
# Per prima cosa, crea un file con un po' di contenuto
with open("demo.txt", "w") as file:
file.write("Original content\n")
# Ora aprilo di nuovo in modalità scrittura
with open("demo.txt", "w") as file:
file.write("New content\n")
# Leggi il file per vedere cosa contiene
with open("demo.txt", "r") as file:
print(file.read())Output:
New contentIl contenuto originale è scomparso. La modalità scrittura parte sempre da un file vuoto, che stia creando un nuovo file o sovrascrivendone uno esistente.
27.6.2) Scrivere più righe
Puoi chiamare write() più volte per scrivere più righe:
with open("shopping_list.txt", "w") as file:
file.write("Apples\n")
file.write("Bananas\n")
file.write("Oranges\n")27.6.3) Scrivere dati da collezioni
Un’attività comune è scrivere su un file dati provenienti da liste o altre collezioni:
students = ["Alice", "Bob", "Carol", "David"]
with open("students.txt", "w") as file:
for student in students:
file.write(student + "\n")Questo crea students.txt contenente:
Alice
Bob
Carol
David27.6.4) Aggiungere contenuto a un file (append)
Quando vuoi aggiungere contenuto alla fine di un file esistente senza cancellare ciò che c’è già, usa la modalità append ('a'):
# Crea un file con contenuto iniziale
with open("log.txt", "w") as file:
file.write("Program started\n")
# Più tardi, aggiungi altro contenuto
with open("log.txt", "a") as file:
file.write("Processing data\n")
file.write("Processing complete\n")
# Leggi il file per vedere tutto il contenuto
with open("log.txt", "r") as file:
print(file.read())Output:
Program started
Processing data
Processing completeLa modalità append è perfetta per i file di log, in cui vuoi mantenere una cronologia continua degli eventi. Ogni volta che apri il file in modalità append, il nuovo contenuto viene aggiunto alla fine, preservando tutto ciò che era già presente.
27.7) Gestire gli errori comuni di I/O su file
Le operazioni sui file possono fallire per molti motivi: il file non esiste, non hai i permessi per accedervi, il disco è pieno o il file è già aperto da un altro programma. Imparare a gestire questi errori in modo elegante rende i tuoi programmi più robusti e user-friendly.
27.7.1) FileNotFoundError: quando un file non esiste
L’errore sui file più comune si verifica quando provi a leggere un file che non esiste:
# ATTENZIONE: questo solleverà FileNotFoundError se data.txt non esiste
with open("data.txt", "r") as file:
content = file.read()Se data.txt non esiste, Python solleva:
FileNotFoundError: [Errno 2] No such file or directory: 'data.txt'Per gestirlo in modo elegante, usa un blocco try-except (come abbiamo imparato nel Capitolo 25):
try:
with open("data.txt", "r") as file:
content = file.read()
print(content)
except FileNotFoundError:
print("Error: The file 'data.txt' was not found.")
print("Please check the filename and try again.")Output (se il file non esiste):
Error: The file 'data.txt' was not found.
Please check the filename and try again.Questo approccio impedisce al programma di andare in crash e fornisce un messaggio utile all’utente.
27.7.2) PermissionError: quando non puoi accedere a un file
A volte non hai il permesso di leggere o scrivere un file:
try:
with open("/root/protected.txt", "r") as file:
content = file.read()
except PermissionError:
print("Error: You don't have permission to access this file.")Gli errori di permesso possono verificarsi quando:
- Il file appartiene a un altro utente
- Il file si trova in una directory di sistema protetta
- Il file è contrassegnato come di sola lettura e stai cercando di scriverci
- Su Windows, il file è aperto in un altro programma
27.7.3) IsADirectoryError: quando provi ad aprire una directory
Se per sbaglio provi ad aprire una directory invece di un file:
try:
with open("my_folder", "r") as file:
content = file.read()
except IsADirectoryError:
print("Error: 'my_folder' is a directory, not a file.")Questo può succedere quando hai sia un file sia una directory con nomi simili, oppure quando dimentichi di includere il nome del file in un percorso.
27.7.4) UnicodeDecodeError: quando la codifica non corrisponde
Se provi a leggere un file con la codifica sbagliata, potresti ottenere un UnicodeDecodeError:
try:
with open("data.txt", "r", encoding="utf-8") as file:
content = file.read()
except UnicodeDecodeError:
print("Error: The file encoding doesn't match UTF-8.")
print("The file might use a different encoding.")Questo errore si verifica quando il file contiene byte che non sono validi UTF-8. Se ti capita, il file potrebbe:
- Usare una codifica diversa (come Latin-1 o Windows-1252)
- Essere un file binario che stai cercando di leggere come testo
- Essere corrotto
27.7.5) Gestire più tipi di errore
Puoi intercettare più tipi di errore in un singolo blocco try-except:
filename = input("Enter filename: ")
try:
with open(filename, "r") as file:
content = file.read()
print(content)
except FileNotFoundError:
print(f"Error: '{filename}' does not exist.")
except PermissionError:
print(f"Error: You don't have permission to read '{filename}'.")
except IsADirectoryError:
print(f"Error: '{filename}' is a directory, not a file.")
except UnicodeDecodeError:
print(f"Error: '{filename}' contains invalid text encoding.")Questo fornisce messaggi di errore specifici e utili per ogni tipo di problema. L’utente sa esattamente cosa è andato storto e può intraprendere l’azione appropriata.
27.7.6) Usare un gestore di eccezioni generico (catch-all)
A volte vuoi intercettare qualsiasi errore imprevisto legato ai file oltre ai tipi specifici che abbiamo coperto. Puoi usare un gestore generale Exception come catch-all dopo i gestori specifici:
filename = input("Enter filename: ")
try:
with open(filename, "r") as file:
content = file.read()
print(content)
except FileNotFoundError:
print(f"Error: '{filename}' not found.")
except PermissionError:
print(f"Error: No permission to read '{filename}'.")
except IsADirectoryError:
print(f"Error: '{filename}' is a directory.")
except UnicodeDecodeError:
print(f"Error: '{filename}' has invalid encoding.")
except Exception as e:
print(f"Unexpected error reading file: {e}")Questo assicura che il programma gestisca anche errori che non avevi previsto. La variabile e contiene l’oggetto eccezione, che include un messaggio di errore descrittivo. Stamparlo fornisce all’utente dettagli tecnici su cosa è andato storto.
Lavorare con i file è una competenza fondamentale nella programmazione. Hai imparato come:
- Comprendere i percorsi dei file e la directory di lavoro corrente
- Aprire e chiudere i file correttamente
- Usare diverse modalità dei file per leggere, scrivere e aggiungere contenuto
- Gestire automaticamente i file con l’istruzione
with - Leggere i file usando vari metodi (
read(),readline(), iterazione,readlines()) - Scrivere e aggiungere contenuto ai file
- Gestire in modo elegante gli errori comuni di I/O su file
Queste competenze ti permettono di creare programmi che persistono dati tra esecuzioni, elaborare file di testo, generare report e molto altro. Nel prossimo capitolo esploreremo in profondità i context manager, comprendendo il meccanismo che fa funzionare l’istruzione with e come creare i tuoi context manager per gestire risorse oltre ai file.