Gestione dei file Python: lettura, scrittura, CSV, JSON e pathlib con esempi

  1. Home
  2. Blog
  3. Sviluppo software

Sviluppo software

Gestione dei file Python: Lettura, scrittura, CSV, JSON e pathlib con esempi

Quasi tutti gli script reali leggono o scrivono un file. Scopri come aprire i file in modo sicuro, scegliere la modalità giusta, gestire CSV e JSON, lavorare con percorsi utilizzando pathlib ed evitare l’errore che cancella i tuoi dati.

9 min di lettura
Gestione dei file Python: lettura, scrittura, CSV, JSON e pathlib con esempi

Punti chiave

  • Apri sempre i file con un blocco with, in modo che si chiudano automaticamente.
  • La modalità "w" cancella un file esistente. Utilizzare "a" per aggiungerne uno o "x" per rifiutare la sovrascrittura.
  • Passa sull’oggetto file per leggere file di grandi dimensioni senza caricare tutto in memoria.
  • Passa encoding="utf-8" esplicitamente e preferisci pathlib per costruire percorsi.

Log, report, configurazione, esportazioni: prima o poi ogni script tocca il file system. La gestione dei file Python è semplice da iniziare, ma alcuni dettagli decidono se il tuo codice è affidabile o distrugge silenziosamente i dati.

Questa guida tratta file di testo, CSV, JSON, dati binari e percorsi, con particolare attenzione alle abitudini sicure. Abbiamo eseguito questi esempi su Python 3.13 in una cartella temporanea e l’output mostrato proviene da quell’esecuzione.

Apri i file con open() e con

La funzione incorporata open() restituisce un oggetto file. Usalo all’interno di un blocco with:

with open("notes.txt", "w", encoding="utf-8") as file:
    file.write("first line\n")
    file.write("second line\n")

print(file.closed)

# True

Quando il blocco termina, Python chiude il file, anche se si è verificato un errore al suo interno. Senza with, devi chiamare tu stesso close() e un’eccezione può saltare quella riga. L’utilizzo di un file dopo la sua chiusura genera un errore:

file.read()

# ValueError: I/O operation on closed file.

Modalità file

Il secondo argomento di open() dice cosa intendi fare:

Modalità Significato Se il file esiste In caso contrario
r Leggi (predefinito) Lo apre Errore
w Scrivi Lo cancella prima Lo crea
un Aggiungi Aggiunge alla fine Lo crea
x Creazione esclusiva Errore Lo crea
r+ Leggi e scrivi Lo apre Errore

Aggiungere b per i dati binari, come in "rb" o "wb". Il testo è l’impostazione predefinita e può anche essere scritto esplicitamente come t.

Scrivi e aggiungi

write() non aggiunge un’interruzione di riga, quindi includi \n tu stesso. L’aggiunta mantiene ciò che è già presente:

with open("notes.txt", "a", encoding="utf-8") as file:
    file.write("third line\n")

Confrontalo con la modalità "w", che ha sostituito le nostre tre righe con una, senza alcun avviso:

with open("notes.txt", "w", encoding="utf-8") as file:
    file.write("replaced\n")

# notes.txt now contains only: replaced

Quando non è necessario sovrascrivere qualcosa, utilizzare "x". Nel nostro test è stato sollevato FileExistsError poiché notes.txt esisteva già.

Leggere un file

Esistono diversi modi per leggere e la scelta giusta dipende dalla dimensione del file:

Avvicinamento Ritorni Meglio per
file.read() Una corda con tutto Piccoli file
file.readline() La riga successiva Leggere un’intestazione
file.readlines() Un elenco di righe Piccoli file necessari come elenco
per la riga nel file Una riga alla volta Qualsiasi dimensione, soprattutto file di grandi dimensioni
with open("notes.txt", encoding="utf-8") as file:
    print(repr(file.read()))

# 'first line\nsecond line\n'

with open("notes.txt", encoding="utf-8") as file:
    for line in file:
        print(line.strip())

# first line
# second line
# third line

Notare i caratteri \n mantenuti nella stringa grezza. strip() li rimuove. Un oggetto file ricorda anche la sua posizione, quindi la lettura continua da dove era stata interrotta:

with open("notes.txt", encoding="utf-8") as file:
    print(file.readline().strip())
    print(file.readlines())

# first line
# ['second line\n', 'third line\n']

Il looping del file è la tecnica chiave per log ed esportazioni di grandi dimensioni. Legge una riga alla volta, quindi un file multi-gigabyte non deve entrare in memoria.

Gestire gli errori dei file

I file potrebbero mancare, essere bloccati o illeggibili, quindi pianificalo:

try:
    with open("missing.txt", encoding="utf-8") as file:
        data = file.read()
except FileNotFoundError as error:
    print(error)

# [Errno 2] No such file or directory: 'missing.txt'
Eccezione Causa tipica
ErroreFileNotFound Il percorso non esiste
FileExistsErrore Modalità x su un file esistente
Errore di autorizzazione Non consentito o bloccato su Windows
IsADirectoryError Il percorso è una cartella
Errore di decodifica Unicode È stata utilizzata la codifica errata

Prova ad aprire il file e a individuare l’errore, invece di controllare prima con exists(), poiché il file potrebbe svanire tra il controllo e l’apertura. La nostra guida alla gestione delle eccezioni Python copre questo approccio.

File CSV

Non dividere tu stesso le righe CSV con una virgola, perché i valori tra virgolette possono contenere virgole. Il modulo standard csv gestisce queste regole. DictWriter e DictReader sono le opzioni più leggibili:

import csv

with open("orders.csv", "w", newline="", encoding="utf-8") as file:
    writer = csv.DictWriter(file, fieldnames=["id", "customer", "total"])
    writer.writeheader()
    writer.writerow({"id": 1, "customer": "Asha", "total": 1200})
    writer.writerow({"id": 2, "customer": "Ben", "total": 300})

with open("orders.csv", newline="", encoding="utf-8") as file:
    rows = list(csv.DictReader(file))

print(rows[0])
print(sum(int(r["total"]) for r in rows))

# {'id': '1', 'customer': 'Asha', 'total': '1200'}
# 1500

Due dettagli contano. Passa newline="" quando si aprono file CSV, come consiglia la documentazione, per evitare righe vuote su Windows. E ogni valore ritorna come una stringa, numeri pari, motivo per cui avevamo bisogno di int() nella somma. Per un lavoro con dati pesanti, una libreria come Panda può essere la soluzione migliore.

File JSON

JSON è il formato abituale per la configurazione e i dati API. Si mappa perfettamente sui dizionari Python ed elenca:

import json

config = {"debug": True, "retries": 3, "hosts": ["a", "b"]}

with open("config.json", "w", encoding="utf-8") as file:
    json.dump(config, file, indent=2)

with open("config.json", encoding="utf-8") as file:
    print(json.load(file)["retries"])

# 3

Ricorda la denominazione: dump e load funzionano con i file, mentre dumps e loads funzionano con le stringhe. Tipi come le date non possono essere memorizzati direttamente, quindi dovrai prima convertirli in stringhe.

Lavora con i percorsi usando pathlib

L’incollaggio di percorsi insieme a stringhe si interrompe tra i sistemi operativi. Il modulo standard pathlib gestisce i separatori per te e offre comode scorciatoie:

from pathlib import Path

path = Path("data") / "reports" / "summary.txt"
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("all good\n", encoding="utf-8")

print(path.read_text(encoding="utf-8").strip())   # all good
print(path.suffix, path.stem, path.exists())      # .txt summary True
print(sorted(p.name for p in Path(".").glob("*.csv")))
# ['orders.csv']
Compito pathlib
Unisci percorsi Percorso("a") / "b.txt"
Crea cartelle percorso.mkdir(genitori=Vero, esiste_ok=Vero)
Leggere o scrivere l’intero testo read_text(), write_text()
Trova file glob("*.csv"), rglob("*.py")
Elimina un file path.unlink()
Ottieni la cartella dello script corrente Path(__file__).parent

Quest’ultimo risolve un mal di testa comune. I percorsi relativi si risolvono da dove hai eseguito lo script, non da dove risiede lo script, quindi costruire percorsi da Path(__file__).parent evita molte sorprese di tipo “file non trovato”.

File binari

Immagini, PDF e file ZIP non sono testo. Aprili con b e leggi e scrivi bytes, senza alcuna codifica coinvolta:

with open("pixel.bin", "wb") as file:
    file.write(bytes([255, 0, 128]))

with open("pixel.bin", "rb") as file:
    print(file.read())

# b'\xff\x00\x80'

Scrive più sicuro

Se un programma si arresta in modo anomalo durante la scrittura di un file importante, è possibile che il risultato venga danneggiato. Una soluzione comune è scrivere prima su un file temporaneo e poi sostituirlo nella sua posizione:

temp = Path("settings.tmp")
temp.write_text("new", encoding="utf-8")
temp.replace("settings.txt")

print(Path("settings.txt").read_text(), temp.exists())

# new False

replace() sovrascrive la destinazione. Sullo stesso file system, la ridenominazione è generalmente atomica, quindi i lettori vedono il vecchio file o quello nuovo anziché un mix scritto a metà.

Suggerimento: non creare mai percorsi di file direttamente dall’input dell’utente senza controllarli. Un valore come ../../secrets.txt potrebbe raggiungere file esterni alla cartella prevista. Questa è nota come vulnerabilità di attraversamento del percorso.

Un esempio pratico: riassumere un log

Questo breve script mette insieme diverse idee. Legge un registro una riga alla volta, quindi la sua dimensione non ha importanza, conta ogni livello utilizzando Counter e scrive un riepilogo in un nuovo file:

from collections import Counter

counts = Counter()
with open("app.log", encoding="utf-8") as file:
    for line in file:
        counts[line.split()[0]] += 1

with open("summary.txt", "w", encoding="utf-8") as out:
    for level, total in counts.most_common():
        out.write(f"{level}: {total}\n")

# summary.txt
# ERROR: 2
# INFO: 2
# WARN: 1

Il nostro registro di esempio aveva cinque righe. Una riga vuota si interromperebbe line.split()[0], quindi gli script reali dovrebbero saltare prima le righe vuote.

Errori comuni

  • Utilizzando "w" quando intendevi "a". I tuoi dati esistenti scompariranno immediatamente all’apertura, anche se non scrivi mai nulla.
  • Omissione della codifica. L’impostazione predefinita varia in base al sistema, quindi uno script che funziona su Linux può fallire su Windows con testo accentato o emoji.
  • Chiamare read() su file di grandi dimensioni. Questo può esaurire la memoria, quindi esegui il loop sulle righe.
  • Dimenticare int() sui valori CSV. "10" + "20" dà "1020".
  • Tralasciare newline="" per CSV. Potresti ottenere righe vuote inaspettate su Windows.
  • Non testare il codice del file. Usa il dispositivo di pytest tmp_path in modo che i test non tocchino mai file reali. Guarda il nostro tutorial pytest.

Considerazioni finali

Alcune abitudini coprono quasi tutto qui: usa with, imposta la codifica, pensaci due volte su "w" e lascia che csv, json e pathlib facciano le parti difficili. Per esercitarti, scrivi un piccolo script che legga un CSV, totalizzi una colonna e salvi un riepilogo JSON in una nuova cartella.

Domande frequenti

Come leggo un file riga per riga in Python?

Aprilo in un blocco with ed esegui il loop sull’oggetto file. Legge una riga alla volta, quindi funziona bene anche per file molto grandi.

Qual è la differenza tra w e una modalità?

La modalità cancella qualsiasi contenuto esistente non appena il file si apre. La modalità a mantiene il contenuto esistente e aggiunge nuovi dati alla fine del file.

Perché dovrei usare with per aprire un file?

L’istruzione with chiude automaticamente il file al termine del blocco, anche se si verifica un errore. Ciò impedisce perdite e aiuta a garantire che i dati vengano scritti.

Come posso verificare se esiste un file in Python?

Utilizza Path(“nome.txt”).exists() da pathlib. Se prevedi di aprirlo subito dopo, rilevare FileNotFoundError è solitamente più affidabile che controllare prima.

Perché il mio CSV ha righe vuote su Windows?

Probabilmente hai aperto il file senza newline=””. Il modulo csv gestisce da solo le terminazioni di riga, quindi passa questo argomento per evitare righe vuote aggiuntive.

Continua a imparare

Lavora con Stack Quora

Hai bisogno di aiuto con test, WordPress o SEO?

Aiutiamo i team a fornire software migliore e a far crescere i loro siti. Raccontaci a cosa stai lavorando e ti suggeriremo chiaramente il prossimo passo.

Continua a leggere

Altre guide su test, intelligenza artificiale e sviluppo moderno

Ti è piaciuto questo articolo? Scegli un argomento e passa direttamente ai nostri tutorial più recenti.

Intelligenza artificiale

Spiegazione delle allucinazioni dell'intelligenza artificiale: perché i modelli linguistici inventano le cose e come ridurle

Spiegazione delle allucinazioni dell'intelligenza artificiale: cosa sono, perché i modelli linguistici le producono, tipi comuni, come ridurle con b…

Leggi l'articolo →
DevOps

Spiegazione delle variabili d'ambiente: file .env, segreti e configurazione eseguiti correttamente

Variabili d'ambiente spiegate con esempi Python che abbiamo eseguito: lettura e impostazione, perché ogni valore è una stringa, file .env, ereditari…

Leggi l'articolo →
Sviluppo software

Spiegazione della limitazione della velocità API: algoritmi, intestazioni e gestione degli errori 429

La limitazione della velocità dell'API spiegata con una simulazione che abbiamo eseguito: bucket di token, finestra fissa, finestra scorrevole, risp…

Leggi l'articolo →
Automazione dei test

Derisione in Python: unittest.mock, patch e gli errori che fanno mentire i test

Mocking in Python con unittest.mock, testato: Mock e return_value, side_effect, patch dove viene utilizzato un nome, specifiche e autospec, date moc…

Leggi l'articolo →
Test del software

Spiegazione della copertura del codice: copertura di linea o di filiale e cosa significa realmente il 100%.

Copertura del codice spiegata con una vera esecuzione di cover.py: copertura di linea, ramo e condizione, lettura di un rapporto, perché la copertur…

Leggi l'articolo →
Database e SQL

DELETE vs TRUNCATE vs DROP in SQL: differenze, rollback e quando utilizzarli

DELETE vs TRUNCATE vs DROP spiegato con SQL testato: cosa rimuove, rollback, trigger, reimpostazione dell'identità, velocità e come differiscono Pos…

Leggi l'articolo →
Database e SQL

Spiegazione delle visualizzazioni SQL: crea, utilizza ed evita le insidie, con esempi

Viste SQL spiegate con le query che abbiamo eseguito: creazione di una vista, risultati in tempo reale, nascondere colonne, prestazioni, viste aggio…

Leggi l'articolo →
Sviluppo software

Interfaccia TypeScript e tipo: differenze reali, testate con il compilatore

Interfaccia TypeScript vs tipo, verificata con il vero compilatore: cosa possono fare entrambi, cosa può fare solo uno, fusione delle dichiarazioni,…

Leggi l'articolo →
Sviluppo software

Spiegazione di Python *args e **kwargs: funzioni flessibili con esempi chiari

Python *args e **kwargs spiegati con il codice che abbiamo eseguito: compressione e decompressione, ordine dei parametri, argomenti solo per parole …

Leggi l'articolo →
Sviluppo software

Funzioni Lambda Python: sintassi, usi reali e quando non usarli

Funzioni lambda Python spiegate con il codice che abbiamo eseguito: sintassi, ordinamento con chiave, mappa e filtro, chiusure, trap dell'associazio…

Leggi l'articolo →
Intelligenza artificiale

Cosa sono gli agenti AI? Come funzionano, con un semplice ciclo di agenti che puoi eseguire

Cosa sono gli agenti IA? Una semplice guida al ciclo dell'agente, agli strumenti, alla memoria e ai guardrail, con un piccolo ciclo Python che abbia…

Leggi l'articolo →
DevOps

Monitoraggio vs osservabilità: la vera differenza, con log, metriche e tracce

Spiegazione del monitoraggio e dell'osservabilità: errori noti e sconosciuti, log, metriche e tracce, una procedura dettagliata sugli incidenti di p…

Leggi l'articolo →
DevOps

Volumi Docker e montaggi di associazione: mantenere i dati del contenitore nel modo giusto

Volumi Docker e montaggi di collegamento spiegati: perché i dati del contenitore scompaiono, volumi denominati, montaggi di collegamento, tmpfs, ese…

Leggi l'articolo →
Automazione dei test

TDD vs BDD: differenze chiave, una caratteristica costruita in entrambi i modi e quando utilizzarli ciascuno

TDD vs BDD spiegato con una funzione di sconto costruita in entrambi i modi: refactoring rosso-verde con il codice che abbiamo eseguito, scenari "Da…

Leggi l'articolo →
Test del software

Test di accettazione da parte dell'utente (UAT): processo, lista di controllo ed esempi reali

Spiegazione del test di accettazione dell'utente: chi lo esegue, in cosa differisce dal QA, un processo in sette fasi, un modello di test case UAT, …

Leggi l'articolo →
Database e SQL

Spiegazione dei valori SQL NULL: IS NULL, COALESCE, NULLIF e le trappole da evitare

Valori SQL NULL spiegati con le query che abbiamo eseguito: logica a tre valori, IS NULL, COALESCE, NULLIF, come aggregazioni, join e ordinamento tr…

Leggi l'articolo →
Database e SQL

Istruzione SQL CASE WHEN: sintassi, esempi reali ed errori comuni

SQL CASE WHEN spiegato con le query che abbiamo eseguito: moduli semplici e cercati, ordine delle condizioni, pivot con SUM, trucchi COUNT, ordiname…

Leggi l'articolo →
Sviluppo software

Cos'è il JWT? Token Web JSON spiegati con un esempio funzionante

Cos'è il JWT? Spiegazione dei token Web JSON: le tre parti, un token creato e manomesso nel codice che abbiamo eseguito, JWT e sessioni, archiviazio…

Leggi l'articolo →
Sviluppo software

Spiegazione del loop di eventi JavaScript: stack di chiamate, microtask e timer con esempi

Il ciclo di eventi JavaScript spiegato con il codice che abbiamo eseguito: stack di chiamate, code di attività e microtask, perché setTimeout 0 non …

Leggi l'articolo →
Sviluppo software

Spiegazione dei generatori Python e del rendimento: risparmia memoria con esempi reali

Generatori Python e rendimento spiegati con il codice che abbiamo eseguito: come vengono messi in pausa e ripresi, misurato il risparmio di memoria,…

Leggi l'articolo →
Intelligenza artificiale

Cosa sono gli incorporamenti? I vettori e la somiglianza del coseno spiegati semplicemente

Cosa sono gli incorporamenti? Una guida in linguaggio semplice ai vettori, alla similarità del coseno e alla ricerca semantica, con un piccolo esemp…

Leggi l'articolo →
DevOps

Distribuzione blu-verde rispetto a quella canaria: differenze, compromessi e come scegliere

Spiegazione della distribuzione blu-verde e canary: come funziona ciascuna, costi, rischi e rollback, bucket utente stabile che abbiamo testato, mig…

Leggi l'articolo →
Automazione dei test

Test instabili: quali sono le cause e come risolverli definitivamente

Test instabili spiegati con demo che abbiamo eseguito: le cause principali, come confermarne e diagnosticarne uno, soluzioni adeguate per tempistich…

Leggi l'articolo →
Test del software

Test di carico e test di stress: differenze, metriche ed esempi k6

Spiegazione del test di carico e dello stress test: cosa dimostra ciascuno, test di picco e di assorbimento, le metriche che contano, perché le medi…

Leggi l'articolo →
Test del software

Caso di test e scenario di test: differenze chiave, esempi e quando utilizzarli

Spiegazione del caso di test e dello scenario di test: definizioni chiare, una tabella affiancata, una funzione di reimpostazione della password pre…

Leggi l'articolo →
Database e SQL

Ottimizzazione delle query SQL: leggi i piani di esecuzione e correggi query lente, con tempistiche

Ottimizzazione delle query SQL testata su un milione di righe: leggi i piani di esecuzione, aggiungi gli indici corretti, correggi filtri non aggior…

Leggi l'articolo →
Database e SQL

SQL UNION vs UNION ALL: differenze, esempi e prestazioni testate

SQL UNION vs UNION ALL spiegati con le query che abbiamo eseguito: duplicati, regole seguite da entrambi, un vero bug di dati, prestazioni misurate,…

Leggi l'articolo →
Sviluppo software

Tutorial sull'API di recupero JavaScript: GET, POST, gestione degli errori e timeout

Un tutorial sull'API JavaScript Fetch testato su un server locale: GET e POST, perché 404 non genera eccezioni, un helper riutilizzabile, stringhe d…

Leggi l'articolo →
Sviluppo software

Gestione dei file Python: lettura, scrittura, CSV, JSON e pathlib con esempi

Gestione dei file Python spiegata con il codice che abbiamo eseguito: modalità aperte, con, lettura di file di grandi dimensioni, CSV, JSON, pathlib…

Leggi l'articolo →
Sviluppo software

Classi e oggetti Python: tutorial OOP con esempi reali

Classi e oggetti Python spiegati con il codice che abbiamo eseguito: __init__, metodi, attributi di classe e istanza, ereditarietà, proprietà, metod…

Leggi l'articolo →
Intelligenza artificiale

Che cos'è un modello linguistico di grandi dimensioni? Come funzionano i LLM, spiegato senza esagerazioni

Cos’è un modello linguistico ampio? LLM spiegati in un linguaggio semplice: token, incorporamenti, attenzione, formazione, finestre di temperatura e…

Leggi l'articolo →
DevOps

Comandi Linux per principianti: la guida essenziale del terminale con esempi

Comandi Linux per principianti, raggruppati per attività: navigazione, file, visualizzazione log, grep, pipe, permessi, processi e archivi, con un e…

Leggi l'articolo →
Automazione dei test

Selenio vs drammaturgo: differenze chiave, codice a confronto e quale scegliere

Selenium vs Playwright a confronto: architettura, attesa, supporto per browser e linguaggio, debug, lo stesso test in entrambi gli strumenti, consig…

Leggi l'articolo →
Test del software

Partizionamento di equivalenza: tecnica di progettazione dei test spiegata con esempi pratici

Spiegazione del partizionamento di equivalenza: come trovare partizioni valide e non valide, esempi funzionanti per età, password e coupon, test che…

Leggi l'articolo →
Test del software

Gravità vs priorità nel test del software: differenze, matrice ed esempi reali

Spiegazione della gravità e della priorità nei test del software: definizioni chiare, una matrice a quattro vie con esempi, scale di livello, chi im…

Leggi l'articolo →
Database e SQL

Esercitazione sulle sottoquery SQL: tipi, sottoquery correlate ed EXISTS con esempi

Un tutorial sulle sottoquery SQL con le query che abbiamo eseguito: sottoquery scalari, IN, FROM e SELECT, sottoquery correlate, EXISTS, trap NOT IN…

Leggi l'articolo →
Database e SQL

Spiegazione di transazioni SQL e ACID: COMMIT, ROLLBACK e livelli di isolamento

Transazioni SQL e ACID spiegate con un bonifico bancario eseguito: COMMIT, ROLLBACK, punti di salvataggio, blocchi, livelli di isolamento, letture s…

Leggi l'articolo →
Sviluppo software

Git merge vs rebase: differenze, esempi e quando usare ciascuno

Git merge vs rebase spiegato con output reale del log, una tabella di confronto, la regola d'oro del rebase e un flusso di lavoro sicuro per i team.

Leggi l'articolo →
Sviluppo software

List comprehension in Python: sintassi, esempi e quando evitarla

List comprehension in Python spiegata: sintassi, filtri, if-else, cicli annidati, tempi misurati e i casi in cui un normale ciclo for è meglio.

Leggi l'articolo →
Database e SQL

SQL JOIN spiegati con esempi (Inner, Left, Right, Full)

Capisci i JOIN SQL passo dopo passo con tabelle e query di esempio: INNER, LEFT, RIGHT, FULL, CROSS e SELF, con errori comuni e consigli sulle prest…

Leggi l'articolo →