In questa lezione impari a
- aprire, leggere e scrivere file con with open()
- scegliere la modalità giusta (r, w, a)
- gestire gli errori con try ed except
- salvare dati strutturati in CSV e JSON
Quando un programma finisce, le variabili spariscono. Per conservare i dati bisogna scriverli in un file sul disco.
Aprire un file con with
Il modo corretto di lavorare con un file è con l'istruzione with: apre il file e lo chiude da solo alla fine del blocco, anche se succede un errore.
with open("saluti.txt", "w") as file:
file.write("Ciao!\n")
file.write("Seconda riga\n")
"\n" è il carattere "a capo". Il file viene creato nella stessa cartella del programma.
Le modalità di apertura
| Modalità | Significato | Se il file non esiste | Se il file esiste |
|---|---|---|---|
"r" |
lettura (predefinita) | errore | lo legge |
"w" |
scrittura | lo crea | lo cancella e riscrive |
"a" |
aggiunta (append) | lo crea | scrive in fondo |
"x" |
creazione | lo crea | errore |
Attenzione:
"w"cancella tutto il contenuto precedente senza chiedere conferma. Per aggiungere righe usa"a".
Leggere un file
with open("saluti.txt", "r") as file:
contenuto = file.read() # tutto il file in una stringa
print(contenuto)
with open("saluti.txt") as file:
for riga in file: # una riga alla volta
print(riga.strip())
Leggere riga per riga è il metodo migliore per i file grandi, perché non carica tutto in memoria. .strip() toglie l'"a capo" finale.
Gestire gli errori: try ed except
Se il file non esiste, open() provoca un errore e il programma si blocca. Con try ed except puoi intercettare l'errore e decidere cosa fare.
try:
with open("dati.txt") as file:
print(file.read())
except FileNotFoundError:
print("Il file non esiste ancora")
except PermissionError:
print("Non hai il permesso di leggere il file")
Funziona con qualunque errore, non solo con i file:
try:
eta = int(input("Età: "))
except ValueError:
print("Devi scrivere un numero!")
File CSV
Un file CSV è una tabella in formato testo: ogni riga è un record, i valori sono separati da virgole. Si apre anche con Excel o con Fogli di Google.
import csv
studenti = [
{"nome": "Anna", "classe": "3B", "media": 7.8},
{"nome": "Luca", "classe": "3B", "media": 6.9},
]
with open("studenti.csv", "w", newline="") as file:
scrittore = csv.DictWriter(file, fieldnames=["nome", "classe", "media"])
scrittore.writeheader()
scrittore.writerows(studenti)
with open("studenti.csv", newline="") as file:
for riga in csv.DictReader(file):
print(f"{riga['nome']}: {riga['media']}")
File JSON
JSON è il formato più usato per scambiare dati tra programmi e sul web. Somiglia moltissimo ai dizionari e alle liste di Python, e il modulo json li converte in un attimo.
import json
rubrica = {"Anna": "333 1234567", "Luca": "347 7654321"}
with open("rubrica.json", "w") as file:
json.dump(rubrica, file, indent=2) # salva
with open("rubrica.json") as file:
caricata = json.load(file) # carica
print(caricata["Anna"])
Esercizi
Esercizio 1 – Il diario. Chiedi all'utente una frase e aggiungila in fondo al file diario.txt. Poi stampa tutto il diario, con le righe numerate.
Mostra la soluzione
frase = input("Cosa è successo oggi? ")
with open("diario.txt", "a") as file:
file.write(frase + "\n")
with open("diario.txt") as file:
for numero, riga in enumerate(file, start=1):
print(f"{numero}. {riga.strip()}")
Esercizio 2 – Contare le parole. Leggi un file di testo e stampa quante righe e quante parole contiene. Se il file non esiste, stampa un messaggio chiaro.
Mostra la soluzione
nome_file = input("Nome del file: ")
try:
with open(nome_file) as file:
righe = file.readlines()
parole = sum(len(riga.split()) for riga in righe)
print(f"{len(righe)} righe, {parole} parole")
except FileNotFoundError:
print(f"Il file {nome_file} non esiste")
.split() divide una riga in parole, usando gli spazi come separatori.
Progetto finale: la rubrica che si ricorda
Riprendi la rubrica della lezione 2 e trasformala in una classe Rubrica che:
- all'avvio carica i contatti da
rubrica.json(se il file non esiste, parte vuota) - ha i metodi
aggiungi(),cerca(),elimina()edelenco() - salva su file ogni volta che i contatti cambiano
Così, quando riapri il programma, i contatti sono ancora lì. Usa tutto quello che hai imparato: dizionari, funzioni, classi, file ed eccezioni.
Mostra la soluzione
import json
class Rubrica:
def __init__(self, nome_file="rubrica.json"):
self.nome_file = nome_file
try:
with open(nome_file) as file:
self.contatti = json.load(file)
except FileNotFoundError:
self.contatti = {}
def salva(self):
with open(self.nome_file, "w") as file:
json.dump(self.contatti, file, indent=2)
def aggiungi(self, nome, telefono):
self.contatti[nome.strip().title()] = telefono.strip()
self.salva()
def cerca(self, nome):
return self.contatti.get(nome.strip().title())
def elimina(self, nome):
nome = nome.strip().title()
if nome in self.contatti:
del self.contatti[nome]
self.salva()
return True
return False
def elenco(self):
return sorted(self.contatti.items())
rubrica = Rubrica()
scelta = ""
while scelta != "0":
print("\n1 Aggiungi 2 Cerca 3 Elimina 4 Elenco 0 Esci")
scelta = input("Scelta: ")
if scelta == "1":
rubrica.aggiungi(input("Nome: "), input("Telefono: "))
elif scelta == "2":
numero = rubrica.cerca(input("Chi cerchi? "))
print(numero if numero else "Contatto non trovato")
elif scelta == "3":
if rubrica.elimina(input("Chi elimini? ")):
print("Eliminato")
else:
print("Contatto non trovato")
elif scelta == "4":
for nome, telefono in rubrica.elenco():
print(f"{nome}: {telefono}")