7 sätt att kontrollera om en fil eller mapp finns i Python

Python-standardbiblioteket innehåller det mesta av den funktionalitet som en utvecklare skulle behöva för att lösa ett problem. I den här handledningen kommer du att lära dig olika sätt att kontrollera existensen av en fil eller katalog med endast inbyggda moduler.

Att kontrollera om en fil eller ett skript är på rätt plats är avgörande för alla CLI-program. Ditt program kan bli värdelöst om en specifik fil inte finns på plats vid körningsögonblicket.

I dagens handledning kommer du att lära dig några snabba sätt att kontrollera om en fil eller mapp finns i Python.

Innan du startar

Innan du utför något kommando nedan, se till att du har Python 3 installerat i ditt system. Öppna din terminal och skriv följande kommando:

python --version
# Python 3.9.5, my result

Om du har en 2.x-version måste du använda kommandot ”python3”. Kolla in vår Python-installationsguide om du inte har Python 3 installerat.

Vi kommer att använda några testfiler tillsammans med den här handledningen, så se till att skapa följande filer:

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

Kommandona ovan skapar en fil att spela med, en testkatalog och en annan fil i testkatalogen. Filerna kan vara tomma eftersom vi inte behöver läsa deras innehåll,

Obs: Om du använder Windows, ställ in den filens enkla filstruktur med en grafisk filhanterare.

Äntligen kommer vi att använda Ipython som vårt interaktiva Python-skal som ger ett snyggt gränssnitt att arbeta med. Detta är bara en vara, därför inte absolut nödvändigt.

pip install ipython

Efter att ha gjort detta får du tillgång till ett vackert Python-skal bara genom att skriva ipython.

Nu är du redo, låt oss dyka ner i sätt att kontrollera om en mapp eller fil finns i Python.

Prova, Öppna och Except

Detta är det enklaste alternativet. Om du försöker öppna en fil som inte finns kommer Python att höja en FileNotFoundError.

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

Vi kan dra fördel av detta och hantera undantaget om filen vi letar efter inte finns.

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

I koden ovan skriver vi ut ett anpassat meddelande och stoppar körningen av programmet om filen inte finns.

Notera hur funktionen exit() endast kommer att köras om ett undantag görs. Låt oss se vad som händer när filen vi letar efter faktiskt existerar.

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'>

Notera hur vi stänger filen direkt efter att vi öppnat den. Det anses vara en god praxis enligt Python dokumentation.

Anropar file.write() utan att använda nyckelordet with eller anropar file.close() kan leda till att argumenten för file.write() inte skrivs helt till disken, även om programmet avslutas.

Även om vi inte skriver till filen, är det extremt rekommenderat att stänga filen eftersom det kan leda till flera prestandaproblem.

Om vi ​​inte vill stänga filen själva, kan vi använda med kontexthanteraren. Den allokerar och släpper resurser exakt, därför behöver vi inte stänga filen.

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'>

Denna metod är extremt användbar när man skriver i filer, men blir ineffektiv om vi bara vill kontrollera om en fil finns. Låt oss dyka in i andra alternativ för att uppnå detta.

os.path.exists()

De os modul ger flera funktioner för att interagera med operativsystemet. För att kontrollera om en fil eller mapp finns kan vi använda funktionen path.exists() som accepterar sökvägen till filen eller katalogen som ett argument. Den returnerar ett booleskt värde baserat på sökvägens existens.

Obs: En sökväg är den unika platsen för en fil eller katalog i ett filsystem

I Python, den os.sökväg undermodulen innehåller funktioner exklusivt utformade för att fungera med filsökvägar. Alla dessa funktioner accepterar sökvägsargumentet som strängar eller byte, och du kan välja att arbeta med absoluta sökvägar, till exempel:

/home/daniel/.bashrc

Eller med relativa sökvägar, beroende på vilken katalog du kör skriptet:

.bashrc
# Running the script in my home folder

Här är flera exempel som använder funktionen os.path.exists() som körs i katalogen som mina testfiler finns:

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

Som du kan se returnerar den True när du testar med filen testfile.txt och testkatalogmappen, och False när filen inte finns.

os.path.isfile()

Om du bara ville bevisa existensen av en fil (inte en katalog), skulle du anropa os.path.isfile()-funktionen.

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

Obs: I UNIX slutar alla kataloger med ett snedstreck (/), medan vi i Windows använder ett snedstreck ().

I koden ovanför returnerar isfile()-funktionen False vid två tillfällen, låt oss se varför:

  • testdirectory/ är en katalog, därför betraktas den inte som en fil. Detta är inte helt sant sedan i Linux allt är en filbeskrivningmen Python behandlar kataloger annorlunda bara för enkelhetens skull (Om du försöker öppna en katalog får du ett IsADirectoryError)
  • i-dont-even-exist pekar på en fil som ironiskt nog inte existerar

os.path.isdir()

Om du vill kontrollera att en katalog är på rätt plats, måste du använda funktionen os.path.isdir() som endast returnerar True om den givna sökvägen pekar till en katalog.

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

Notera hur exemplen ovan returnerar False även när sökvägen pekar på en fil som finns.

Glob

De glob modul ger funktioner att arbeta med Unix skalliknande mönster (därför fungerar det inte korrekt på Windows). För att kontrollera om en fil matchar ett mönster i den aktuella katalogen kan du använda glob.glob() fungera.

In [1]: import glob

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

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

I koden ovan är mönstret som skickas till glob-funktionen en normal sträng som representerar sökvägen till testfilen och katalogen. Eftersom båda sökvägarna finns, returnerar funktionen en lista med de matchande sökvägarna inuti den.

Obs: Om mönstret inte matchade skulle du få en tom lista.

Med tanke på att vi kan överföra mönster till globfunktionen, varför inte testa några av de främsta fördelarna med den?

Koden nedan får alla filsökvägar med filtillägget .txt respektive .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']

Använda Path Class

De Banklass är ett av de bästa sätten att arbeta med sökvägar eftersom det ger oss ett rent gränssnitt för att arbeta med filsökvägar som objekt.

Körsbäret i kakan är att Path-instanser har alla metoder du behöver för att få information om en viss väg. Detta inkluderar liknande funktioner som de tidigare alternativen.

Obs: Du behöver Python 3.4 eller senare för att använda pathlib-biblioteket

De sökvägsmetoder du kommer att använda:

Kontrollera om en sökväg finns

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

Fungerar på samma sätt som os.path.exists().

Kontrollera om sökvägen pekar på en fil

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

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

Motsvarar os.path.isfile().

Kontrollera om sökvägen pekar till en katalog

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

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

Motsvarar os.path.isdir().

delprocess

Om du är en älskare av delprocessmoduler måste du känna till det här alternativet. Du kan avgöra om en fil eller mapp finns genom att använda testkommando.

Obs: Testkommandot fungerar bara i Unix.

Följande testflaggor kommer att få jobbet gjort:

  • test -e: Kontrollera om en sökväg finns
  • test -f: Kontrollera om en fil finns
  • test-d: Kontrollera om det finns en mapp

Om du vill dyka in i fler testflaggor kan du läsa manualen genom att köra:

man test

Kontrollera en sökväg med underprocess:

Koden nedan avgör om det finns en sökväg genom att jämföra returkoden för underprocessen med 0.

Kom ihåg att i Linux, om en process gick bra, kommer den att returnera noll, om den inte gjorde det kommer den att returnera någon annan kod.

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

I det första uttalandet importerar vi delprocessmodulen och använder sedan kör funktion och får dess returkod.

Verifiera existensen av en fil med underprocess

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

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

Kontrollera en katalog med underprocess:

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

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

Det är inte så rekommenderat att använda det här alternativet eftersom det förbrukar mer resurser och vi får ingen fördel av det.

För att sammanfatta

Python är ett av de mest använda programmeringsspråken för att automatisera processer genom att interagera med operativsystemet. En cool sak du kan göra med den är att kontrollera om en fil eller en mapp finns.

Det enklaste att göra det är:

  • Öppna och hantera filundantag direkt
  • Använder funktionen exists() för modulerna os.path eller pathlib.

I den här handledningen lärde du dig:

  • Hur man öppnar en fil och hanterar undantag om den inte existerar
  • Betydelsen av stigar
  • 3 olika funktioner undermodulen os.path tillhandahåller för att kontrollera existensen av en fil eller mapp
  • Unix använder snedstreck framåt (/), medan Windows använder snedstreck ()

Läs nästa: Vad är en underprocess i Python? [5 Usage Examples]