W3docs

Gestione dei file in Python: una guida completa

Impara la gestione dei file in Python: apri i file in ogni modalità, leggi e scrivi dati, usa pathlib, gestisci gli errori e naviga nelle posizioni del file.

La gestione dei file consente ai tuoi programmi di memorizzare i dati in modo permanente e recuperarli in seguito. Questo capitolo spiega ogni operazione comune sui file in Python — apertura dei file in diverse modalità, lettura e scrittura dei dati, navigazione all'interno di un file, specificazione della codifica dei caratteri e gestione degli errori che emergono nel codice reale.

La funzione open()

Ogni operazione sui file in Python inizia con open(). Restituisce un oggetto file che espone metodi per leggere, scrivere e posizionarsi all'interno del file.

file_object = open(file, mode="r", encoding=None)
  • file — il percorso del file (una string o un oggetto pathlib.Path).
  • mode — come aprire il file (vedi la tabella qui sotto).
  • encoding — la codifica del testo, ad es. "utf-8". Specificala sempre per i file di testo in modo che il codice funzioni allo stesso modo su qualsiasi sistema operativo.

Modalità di apertura dei file

ModalitàSignificatoCrea il file?Tronca il file esistente?
"r"Lettura (predefinita)NoNo
"w"Scrittura
"a"AggiuntaNo
"x"Creazione esclusivaFallisce se il file esiste
"r+"Lettura e scritturaNoNo
"b"Binario (combinare con le precedenti, es. "rb")
"t"Testo (predefinito, combinare con le precedenti, es. "rt")

Usa sempre with per aprire i file

L'istruzione with (un context manager) garantisce che il file venga chiuso quando il blocco termina — anche se viene sollevata un'eccezione. Questo previene le perdite di risorse e assicura che le scritture bufferizzate vengano scaricate su disco.

Apri un file in modo sicuro con with

with open("notes.txt", "r", encoding="utf-8") as f:
    contents = f.read()
# File is automatically closed here

Chiamare open() senza with e dimenticare file.close() è una fonte comune di corruzione dei dati ed errori "troppi file aperti" nei programmi a lunga esecuzione.

Lettura dei file

Python fornisce diversi modi per leggere il contenuto di un file.

Leggi l'intero file con read()

read() restituisce il contenuto completo del file come singola string.

Leggi un intero file

with open("notes.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print(content)

Per i file di grandi dimensioni, questo carica tutto in memoria in una volta sola, il che va bene per i file piccoli ma è inefficiente per i log da diversi gigabyte.

Leggi un numero fisso di caratteri

Passa un intero a read(n) per leggere al massimo n caratteri.

Leggi i primi 20 caratteri

with open("notes.txt", "r", encoding="utf-8") as f:
    chunk = f.read(20)
    print(repr(chunk))

Leggi una riga alla volta con readline()

readline() restituisce la riga successiva incluso il \n finale, oppure una string vuota alla fine del file.

Leggi un file riga per riga con readline()

with open("notes.txt", "r", encoding="utf-8") as f:
    line = f.readline()
    while line:
        print(line, end="")   # line already contains '\n'
        line = f.readline()

Itera sulle righe (il metodo più pythonic)

Iterare direttamente su un oggetto file è l'approccio più efficiente in termini di memoria per la lettura riga per riga.

Itera sulle righe

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

Leggi tutte le righe in una lista con readlines()

readlines() restituisce una lista in cui ogni elemento è una riga (con il carattere di nuova riga incluso).

Leggi tutte le righe in una lista

with open("notes.txt", "r", encoding="utf-8") as f:
    lines = f.readlines()

print(lines[0])   # first line
print(len(lines)) # total number of lines

Usa readlines() quando hai bisogno di accesso casuale a righe specifiche tramite indice. Per l'elaborazione sequenziale, preferisci il pattern for line in f.

Scrittura dei file

Modalità scrittura ("w")

La modalità scrittura crea il file se non esiste e lo tronca (svuota) se esiste.

Scrivi testo in un file

with open("output.txt", "w", encoding="utf-8") as f:
    f.write("Line one\n")
    f.write("Line two\n")

Scrivi più righe con writelines()

writelines() accetta un iterabile di string. Non aggiunge automaticamente caratteri di nuova riga.

Scrivi una lista di righe

lines = ["apple\n", "banana\n", "cherry\n"]

with open("fruits.txt", "w", encoding="utf-8") as f:
    f.writelines(lines)

Modalità aggiunta ("a")

La modalità aggiunta sposta la posizione di scrittura alla fine del file prima di ogni scrittura, quindi il contenuto esistente non viene mai sovrascritto.

Aggiungi una voce di log

import datetime

entry = f"{datetime.date.today()} — task complete\n"

with open("log.txt", "a", encoding="utf-8") as f:
    f.write(entry)

Ogni volta che questo script viene eseguito aggiunge una nuova riga a log.txt senza toccare le voci precedenti.

Modalità creazione esclusiva ("x")

Usa "x" quando vuoi creare un nuovo file e garantire di non sovrascrivere uno esistente. Python solleva FileExistsError se il file esiste già.

Crea un file solo se non esiste

try:
    with open("config.txt", "x", encoding="utf-8") as f:
        f.write("[settings]\n")
except FileExistsError:
    print("config.txt already exists — not overwriting.")

Posizioni nel file: seek() e tell()

Gli oggetti file mantengono un puntatore di posizione interno che avanza man mano che leggi o scrivi. Puoi ispezionare e modificare questo puntatore.

  • tell() — restituisce la posizione in byte corrente.
  • seek(offset, whence=0) — sposta il puntatore. whence=0 (predefinito) è dall'inizio, 1 è dalla posizione corrente, 2 è dalla fine.

Torna all'inizio con seek(0)

with open("notes.txt", "r", encoding="utf-8") as f:
    first_pass = f.read()
    f.seek(0)              # go back to the start
    second_pass = f.read()

print(first_pass == second_pass)  # True

seek() è particolarmente utile nella modalità "r+" (lettura e scrittura) dove potresti leggere una sezione e poi sovrascriverla nella stessa chiamata di apertura.

Lavorare con i file binari

Apri un file in modalità binaria aggiungendo "b" alla string della modalità ("rb", "wb", "ab"). La modalità binaria fornisce byte grezzi invece di string, il che è essenziale per immagini, audio, archivi compressi e altri dati non testuali.

Copia un file in modalità binaria

with open("photo.jpg", "rb") as src:
    data = src.read()

with open("photo_backup.jpg", "wb") as dst:
    dst.write(data)

Non specificare encoding quando si usa la modalità binaria — Python solleverà un ValueError se ci provi.

Gestione degli errori

Le operazioni sui file possono fallire in modi prevedibili. Avvolgerle in blocchi try/except rende i tuoi script robusti.

Gestisci gli errori comuni sui file

try:
    with open("data.txt", "r", encoding="utf-8") as f:
        content = f.read()
except FileNotFoundError:
    print("Error: the file does not exist.")
except PermissionError:
    print("Error: you do not have permission to read this file.")
except OSError as e:
    print(f"OS error: {e}")

Eccezioni comuni che incontrerai:

EccezioneQuando si verifica
FileNotFoundErrorLettura di un file che non esiste
FileExistsErrorCreazione di un file con modalità "x" quando esiste già
PermissionErrorMancanza di permessi di lettura/scrittura
IsADirectoryErrorTentativo di aprire una directory come file
UnicodeDecodeErrorI byte del file non corrispondono alla codifica specificata

L'alternativa moderna con pathlib

Python 3.4 ha introdotto pathlib.Path, un approccio orientato agli oggetti ai percorsi del file system. Gli oggetti Path funzionano perfettamente con open() ed espongono anche i propri metodi di convenienza read_text() / write_text().

Leggi un file con pathlib

from pathlib import Path

content = Path("notes.txt").read_text(encoding="utf-8")
print(content)

Scrivi un file con pathlib

from pathlib import Path

Path("output.txt").write_text("Hello, world!\n", encoding="utf-8")

read_text() e write_text() aprono e chiudono il file per te, rendendo le letture e le scritture in un'unica operazione molto concise. Usa open() con un blocco with quando hai bisogno di un controllo più fine — ad esempio, leggere un file in blocchi o usare seek().

Rinominare e spostare i file

Per rinominare o spostare un file, usa os.rename() per una ridenominazione sullo stesso filesystem, o shutil.move() quando devi spostare tra filesystem diversi.

Rinomina un file con os.rename()

import os

os.rename("old_name.txt", "new_name.txt")

Sposta un file con shutil.move()

import shutil

shutil.move("report.txt", "archive/report.txt")

shutil.move() funziona anche quando sorgente e destinazione si trovano su unità diverse; os.rename() in quel caso solleva OSError.

Verificare se un file esiste

Prima di aprire un file per la lettura, potresti voler confermare che esiste. Usa os.path.exists() o l'equivalente con pathlib.

Verifica l'esistenza con os.path

import os

if os.path.exists("data.txt"):
    print("File found.")
else:
    print("File not found.")

Verifica l'esistenza con pathlib

from pathlib import Path

p = Path("data.txt")
if p.exists():
    print("File found.")

Nota che os.path.exists() e Path.exists() possono restituire risultati non aggiornati in programmi multi-thread o multi-processo. In questi casi, è preferibile aprire direttamente il file con open() e intercettare FileNotFoundError.

Riepilogo delle funzioni principali

OperazioneApproccio con os / shutilApproccio con pathlib
Apri e leggiopen(path, "r")Path(path).read_text()
Apri e scriviopen(path, "w")Path(path).write_text()
Verifica esistenzaos.path.exists(path)Path(path).exists()
Rinominaos.rename(src, dst)Path(src).rename(dst)
Spostashutil.move(src, dst)Path(src).rename(dst) (stesso FS)
Eliminaos.remove(path)Path(path).unlink()

Capitoli correlati

Was this page helpful?