7 modi per verificare se un file o una cartella esiste in Python

La libreria standard di Python contiene la maggior parte delle funzionalità di cui uno sviluppatore avrebbe bisogno per risolvere un problema. In questo tutorial imparerai diversi modi per verificare l’esistenza di un file o di una directory usando solo i moduli incorporati.

Verificare se un file o uno script si trova nel punto corretto è fondamentale per qualsiasi programma CLI. Il tuo programma potrebbe diventare inutile se un file specifico non è presente al momento dell’esecuzione.

Nel tutorial di oggi imparerai alcuni modi rapidi per verificare se un file o una cartella esiste in Python.

Prima di cominciare

Prima di eseguire qualsiasi comando di seguito, assicurati di aver installato Python 3 nel tuo sistema. Apri il tuo terminale e digita il seguente comando:

python --version
# Python 3.9.5, my result

Se hai una versione 2.x, dovrai usare il comando “python3”. Consulta la nostra guida all’installazione di Python se non hai installato Python 3.

Useremo alcuni file di test insieme a questo tutorial, quindi assicurati di creare i seguenti file:

touch testfile.txt
mkdir testdirectory/ 
touch testdirectory/otherfile.txt

I comandi precedenti creano un file con cui giocare, una directory testing e un altro file all’interno della directory testing. I file possono essere vuoti poiché non avremo bisogno di leggerne il contenuto,

Nota: se utilizzi Windows, imposta la struttura di file semplice del file con un file manager grafico.

Infine, useremo Ipython come la nostra shell Python interattiva che offre una bella interfaccia con cui lavorare. Questa è solo una merce, quindi non strettamente necessaria.

pip install ipython

Dopo averlo fatto, avrai accesso a una bellissima shell Python semplicemente digitando ipython.

Ora sei pronto, passiamo ai modi per verificare se esiste una cartella o un file in Python.

Prova, Apri e Tranne

Questa è l’opzione più semplice. Se provi ad aprire un file che non esiste, Python solleverà un file FileNotFoundError.

In [1]: open('im-not-here.txt')
---------------------------------------------------------------------------
FileNotFoundError: [Errno 2] No such file or directory: 'im-not-here.txt'

Possiamo trarne vantaggio e gestire l’eccezione nel caso in cui il file che stiamo cercando non esista.

In [2]: try:
   ...:     file = open('im-not-here.txt')
   ...:     print(file) # File handler
   ...:     file.close()
   ...: except FileNotFoundError:
   ...:     print('Sorry the file we're looking for doesn' exist')
   ...:     exit()
   ...: 
Sorry the file we're looking for doesn't exist

Nel codice sopra stiamo stampando un messaggio personalizzato e interrompendo l’esecuzione del programma se il file non esiste.

Nota come la funzione exit() verrà eseguita solo se viene sollevata un’eccezione. Vediamo cosa succede quando il file che stiamo cercando esiste davvero.

In [2]: try:
   ...:     file = open('testfile.txt')
   ...:     print(file) # File handler
   ...:     file.close()
   ...: except FileNotFoundError:
   ...:     print('Sorry the file we're looking for doesn't exist')
   ...:     exit()
   ...: 
<_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>

Nota come stiamo chiudendo il file subito dopo averlo aperto. È considerata una buona pratica secondo il Documentazione Python.

Chiamare file.write() senza utilizzare la parola chiave with o chiamare file.close() potrebbe far sì che gli argomenti di file.write() non vengano scritti completamente sul disco, anche se il programma si chiude correttamente.

Anche se non stiamo scrivendo sul file, è estremamente consigliato chiudere il file perché potrebbe portare a molteplici problemi di prestazioni.

Se non vogliamo chiudere il file da soli, potremmo usare il with context manager. Alloca e rilascia le risorse in modo preciso, quindi non avremo bisogno di chiudere il file.

In [3]: try:
   ...:     with open('testfile.txt') as file:
   ...:         print(file)
   ...:         # No need to close the file
   ...: except FileNotFoundError:
   ...:     print('Sorry the file we're looking for doesn't exist')
   ...:     exit()
   ...: 
   ...: 
<_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>

Questo metodo è estremamente utile quando si scrive su file, ma risulta inefficiente se si vuole solo controllare se un file esiste. Immergiamoci in altre opzioni per raggiungere questo obiettivo.

os.percorso.esiste()

Il modulo os fornisce molteplici funzioni per interagire con il sistema operativo. Per verificare se esiste un file o una cartella, possiamo utilizzare la funzione path.exists() che accetta il percorso del file o della directory come argomento. Restituisce un valore booleano basato sull’esistenza del percorso.

Nota: un percorso è la posizione univoca di un file o di una directory in un file system

In Python, il percorso.os submodule contiene funzioni progettate esclusivamente per operare con percorsi di file. Tutte queste funzioni accettano l’argomento del percorso come stringhe o byte e puoi decidere di lavorare con percorsi assoluti, ad esempio:

/home/daniel/.bashrc

O con percorsi relativi, a seconda della directory in cui stai eseguendo lo script:

.bashrc
# Running the script in my home folder

Ecco più esempi che utilizzano la funzione os.path.exists(), in esecuzione nella directory in cui si trovano i miei file di test:

In [1]: import os

In [2]: os.path.exists('testfile.txt')
Out[2]: True

In [3]: os.path.exists('testdirectory')
Out[3]: True

In [4]: os.path.exists('hey-i-dont-exist')
Out[4]: False

Come puoi vedere, restituisce True durante il test con il file testfile.txt e la cartella testdirectory e False quando il file non esiste.

os.path.isfile()

Se volessi solo provare l’esistenza di un file (non una directory), chiameresti la funzione os.path.isfile().

In [1]: import os

In [2]: os.path.isfile('testfile.txt')
Out[2]: True

In [3]: os.path.isfile('testdirectory/')
Out[3]: False

In [4]: os.path.isfile('i-dont-even-exist')
Out[4]: False

In [5]: os.path.isfile('testdirectory/otherfile.txt')
Out[5]: True

Nota: in UNIX tutte le directory terminano con una barra (/), mentre in Windows usiamo una barra rovesciata ().

Nel codice sopra la funzione isfile() restituisce False in due occasioni, vediamo perché:

  • testdirectory/ è una directory, quindi non è considerata come un file. Questo non è assolutamente vero poiché in Linux tutto è un descrittore di filema Python tratta le directory in modo diverso solo per comodità (se provi ad aprire una directory otterrai un IsADirectoryError)
  • i-dont-even-exist sta puntando a un file che ironicamente non esiste

os.percorso.isdir()

Se vuoi controllare che una directory sia nel punto corretto, dovrai usare la funzione os.path.isdir(), che restituisce True solo se il percorso indicato punta a una directory.

In [1]: import os

In [2]: os.path.isdir('testfile.txt')
Out[2]: False

In [3]: os.path.isdir('testdirectory')
Out[3]: True

In [4]: os.path.isdir('anotherfile.txt')
Out[4]: False

Nota come gli esempi precedenti restituiscono False anche quando il percorso punta a un file esistente.

Globo

Il globo Il modulo fornisce funzioni con cui lavorare Modelli simili a shell Unix (quindi non funziona correttamente su Windows). Per verificare se un file corrisponde a un modello all’interno della directory corrente, puoi utilizzare il file globo.glob() funzione.

In [1]: import glob

In [2]: glob.glob('testfile.txt')
Out[2]: ['testfile.txt']

In [3]: glob.glob('testdirectory')
Out[3]: ['testdirectory']

Nel codice precedente, il pattern passato alla funzione glob è una stringa normale che rappresenta il percorso del file e della directory di test. Poiché esistono entrambi i percorsi, la funzione restituisce un elenco con i percorsi corrispondenti al suo interno.

Nota: se il modello non corrisponde, otterrai un elenco vuoto.

Considerando che possiamo passare modelli alla funzione glob, perché non provarne alcuni dei principali vantaggi?

Il codice seguente ottiene tutti i percorsi dei file rispettivamente con estensione .txt e .py:

In [4]: glob.glob('*.txt')
Out[4]: ['testfile.txt']

In [5]: glob.glob('*.py')
Out[5]: 
['pathlib-exists.py',
 'list-dir.py',
 'glob-file.py',
 'open-except.py',
 'subprocess-test.py',
 'isfile.py',
 'exists.py',
 'isdir.py']

Utilizzo della classe Path

Il Classe di percorso è uno dei modi migliori per lavorare con i percorsi poiché ci offre un’interfaccia pulita per lavorare con i percorsi dei file come oggetti.

La ciliegina sulla torta è che le istanze Path hanno tutti i metodi necessari per ottenere informazioni su un determinato percorso. Ciò include funzionalità simili alle opzioni precedenti.

Nota: avrai bisogno di Python 3.4 o successivo per usare la libreria pathlib

I metodi Path che utilizzerai:

Controlla se esiste un percorso

In [1]: from pathlib import Path

In [2]: Path('testfile.txt').exists()
Out[2]: True

In [3]: Path('im-not-here.txt').exists()
Out[3]: False

In [4]: Path('testdirectory').exists()
Out[4]: True

Funziona allo stesso modo di os.path.exists().

Controlla se il percorso punta a un file

In [5]: Path('testfile.txt').is_file()
Out[5]: True

In [6]: Path('testdirectory').is_file()
Out[6]: False

Equivalente a os.path.isfile().

Controlla se il percorso punta a una directory

In [7]: Path('testfile.txt').is_dir()
Out[7]: False

In [8]: Path('testdirectory').is_dir()
Out[8]: True

Corrisponde a os.path.isdir().

sottoprocesso

Se sei un amante del modulo di sottoprocesso, devi conoscere questa opzione. È possibile determinare se esiste un file o una cartella utilizzando l’estensione comando di prova.

Nota: il comando test funziona solo in Unix.

I seguenti flag di test completeranno il lavoro:

  • test -e: controlla se esiste un percorso
  • test -f: controlla se esiste un file
  • test-d: controlla se esiste una cartella

Nel caso in cui desideri approfondire più flag di test, puoi leggere il manuale eseguendo:

man test

Controllo di un percorso con sottoprocesso:

Il codice seguente determina se esiste un percorso confrontando il codice di ritorno del sottoprocesso con 0.

Ricorda che in Linux, se un processo è andato bene, restituirà zero, in caso contrario restituirà qualsiasi altro codice.

In [1]: from subprocess import run

In [2]: run(['test', '-e', 'testfile.txt']).returncode == 0
Out[2]: True

In [3]: run(['test', '-e', 'im-not-here.txt']).returncode == 0
Out[3]: False

Nella prima istruzione, stiamo importando il modulo subprocess, quindi utilizzando il file funzione di esecuzione e ottenere il suo codice di ritorno.

Verifica dell’esistenza di un file con sottoprocesso

In [4]: run(['test', '-f', 'testfile.txt']).returncode == 0
Out[4]: True

In [5]: run(['test', '-f', 'testdirectory']).returncode == 0
Out[5]: False

Controllo di una directory con sottoprocesso:

In [6]: run(['test', '-d', 'testfile.txt']).returncode == 0
Out[6]: False

In [7]: run(['test', '-d', 'testdirectory']).returncode == 0
Out[7]: True

Non è consigliabile utilizzare questa opzione poiché consuma più risorse e non ne traiamo alcun vantaggio.

Per riassumere

Python è uno dei linguaggi di programmazione più utilizzati per automatizzare i processi interagendo con il sistema operativo. Una cosa interessante che puoi fare con esso è controllare se esiste un file o una cartella.

I più semplici per farlo sono:

  • Apertura e gestione immediata delle eccezioni di file
  • Usando la funzione exists() dei moduli os.path o pathlib.

In questo tutorial hai imparato:

  • Come aprire un file e gestire le eccezioni nel caso in cui non esista
  • Il significato dei percorsi
  • 3 diverse funzioni fornite dal sottomodulo os.path per verificare l’esistenza di un file o di una cartella
  • Unix utilizza le barre (/), mentre Windows utilizza le barre rovesciate ()

Prossima lettura: Cos’è un sottoprocesso in Python? [5 Usage Examples]