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.
Innehållsförteckning
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]