Utforska fil- och kataloghantering i Python
Pythons standardbibliotek erbjuder ett omfattande utbud av verktyg och funktioner som utvecklare kan utnyttja för att lösa diverse problem. I den här guiden kommer vi att undersöka olika metoder för att verifiera existensen av filer och kataloger, enbart med hjälp av inbyggda moduler.
Att säkerställa att nödvändiga filer eller skript finns på rätt plats är fundamentalt för alla kommandoradsapplikationer. Om en specifik fil saknas vid körningstillfället kan din applikation bli obrukbar.
I denna genomgång kommer du att bekanta dig med effektiva sätt att avgöra om en fil eller mapp finns i Python.
Innan vi börjar
Innan du påbörjar någon av de kommande åtgärderna, försäkra dig om att du har Python 3 installerat på ditt system. Du kan verifiera detta genom att öppna din terminal och ange följande kommando:
python --version # Exempelresultat: Python 3.9.5
Om du har en version 2.x måste du använda kommandot ”python3”. Om du inte har Python 3 installerat, hänvisar vi till vår Python-installationsguide.
Vi kommer att använda några testfiler under den här genomgången, så se till att skapa följande strukturer:
touch testfile.txt mkdir testdirectory/ touch testdirectory/otherfile.txt
Ovanstående kommandon genererar en fil för experimentering, en testkatalog, samt en annan fil inne i testkatalogen. Filerna kan vara tomma eftersom vi inte kommer att fokusera på deras innehåll.
Obs: Om du använder Windows kan du skapa motsvarande filstruktur genom en grafisk filhanterare.
Slutligen kommer vi att använda Ipython som vårt interaktiva Python-skal för ett mer användarvänligt gränssnitt. Detta är valfritt.
pip install ipython
Efter installationen kan du öppna en förbättrad Python-miljö genom att skriva “ipython” i terminalen.
Nu är du redo att utforska olika sätt att verifiera fil- och katalogexistens i Python.
Felhantering med try, open och except
En enkel metod är att utnyttja felhantering. Om man försöker öppna en fil som inte existerar genererar Python ett FileNotFoundError.
In [1]: open('im-not-here.txt') --------------------------------------------------------------------------- FileNotFoundError: [Errno 2] No such file or directory: 'im-not-here.txt'
Vi kan dra nytta av detta genom att hantera undantaget när filen vi söker saknas.
In [2]: try: ...: file = open('im-not-here.txt') ...: print(file) # Filhandtag ...: file.close() ...: except FileNotFoundError: ...: print('Filen vi söker finns tyvärr inte') ...: exit() ...: Filen vi söker finns tyvärr inte
I exemplet ovan ger vi ett anpassat felmeddelande och avslutar programmets körning om filen inte finns.
Lägg märke till att “exit()” endast anropas om ett fel uppstår. Låt oss se vad som händer om filen faktiskt existerar.
In [2]: try: ...: file = open('testfile.txt') ...: print(file) # Filhandtag ...: file.close() ...: except FileNotFoundError: ...: print('Filen vi söker finns tyvärr inte') ...: exit() ...: <_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>
Observera hur vi stänger filen direkt efter att den öppnats, vilket anses vara god praxis enligt Pythons dokumentation.
Anrop av file.write() utan att använda nyckelordet with eller anrop av file.close() kan leda till att informationen från file.write() inte helt skrivs till disk, även efter att programmet avslutas.
Även om vi inte skriver till filen är det rekommenderat att stänga den för att undvika potentiella prestandaproblem.
Om vi inte vill stänga filen manuellt kan vi använda en kontextmanager, med nyckelordet “with”. Denna metod allokerar och frigör resurser på ett exakt sätt, vilket eliminerar behovet av manuell stängning.
In [3]: try: ...: with open('testfile.txt') as file: ...: print(file) ...: # Filen behöver inte stängas manuellt ...: except FileNotFoundError: ...: print('Filen vi söker finns tyvärr inte') ...: exit() ...: ...: <_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>
Denna teknik är särskilt fördelaktig vid filskrivning, men är inte optimal om målet endast är att verifiera en fils existens. Låt oss utforska andra metoder.
Användning av os.path.exists()
os-modulen tillhandahåller diverse 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 som argument och 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 innehåller undermodulen os.path funktioner specifikt utformade för att hantera filsökvägar. Dessa funktioner accepterar sökvägar som strängar eller byte och du kan välja att arbeta med antingen absoluta sökvägar, till exempel:
/home/daniel/.bashrc
eller relativa sökvägar, beroende på från vilken katalog skriptet körs:
.bashrc # Om skriptet körs i hemkatalogen
Här är några exempel som illustrerar användningen av funktionen “os.path.exists()” i den katalogen där testfilerna 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 ser returnerar den “True” vid test av “testfile.txt” och “testdirectory”, och “False” när filen inte existerar.
Användning av os.path.isfile()
Om ditt mål endast är att verifiera existensen av en fil (och inte en katalog) kan du använda funktionen “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
Obs: I UNIX slutar kataloger med ett snedstreck (/), medan Windows använder ett omvänt snedstreck (\).
I koden ovan returnerar “isfile()” “False” i två fall, låt oss se varför:
- “testdirectory/” är en katalog, och betraktas därför inte som en fil. Detta är inte helt sant, eftersom i Linux allt är en filbeskrivning, men Python hanterar kataloger annorlunda av praktiska skäl (om du försöker öppna en katalog resulterar det i ett “IsADirectoryError”).
- “i-dont-even-exist” refererar till en fil som inte existerar.
Användning av os.path.isdir()
För att kontrollera att en katalog finns på rätt plats, kan du använda funktionen “os.path.isdir()”, som endast returnerar “True” om den angivna sökvägen leder 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
Observera att exemplen ovan returnerar “False” även när sökvägen pekar på en befintlig fil.
Användning av Glob
glob-modulen erbjuder funktioner för att hantera Unix-liknande mönster (vilket gör att den inte fungerar korrekt i Windows). För att kontrollera om en fil matchar ett mönster i den aktuella katalogen kan du använda funktionen glob.glob().
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” en normal sträng som representerar sökvägen till testfilen och katalogen. Eftersom båda sökvägarna existerar, 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 skicka in mönster till “glob”, varför inte testa några av dess fördelar?
Koden nedan hämtar alla filsökvägar med filändelsen “.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ändning av Path Class
Path-klassen är en av de mest användarvänliga metoderna för att hantera sökvägar, då den tillhandahåller ett rent gränssnitt för att arbeta med filsökvägar som objekt.
En stor fördel är att Path-instanser har alla metoder du behöver för att hämta information om en viss sökväg, inklusive funktioner som liknar de tidigare alternativen.
Obs: Du behöver Python 3.4 eller senare för att kunna använda pathlib-biblioteket.
Följande sökvägsmetoder är användbara:
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 på 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().
Användning av subprocess
Om du är en användare av delprocessmoduler kan du använda testkommandot för att avgöra om en fil eller mapp finns.
Obs: Testkommandot fungerar enbart i Unix.
Följande testflaggor kan användas för att uppnå detta:
- test -e: Kontrollera om en sökväg existerar
- test -f: Kontrollera om en fil existerar
- test-d: Kontrollera om en mapp existerar
För mer information om testflaggor kan du läsa manualen genom att köra:
man test
Kontrollera en sökväg med hjälp av subprocess:
Koden nedan avgör om en sökväg finns genom att jämföra returkoden för delprocessen med 0.
I Linux returnerar en lyckad process 0, medan en misslyckad process returnerar en 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 steget importerar vi delprocessmodulen, sedan använder vi run-funktionen och hämtar dess returkod.
Verifiera en fils existens med subprocess
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 subprocess:
In [6]: run(['test', '-d', 'testfile.txt']).returncode == 0 Out[6]: False In [7]: run(['test', '-d', 'testdirectory']).returncode == 0 Out[7]: True
Detta alternativ är inte rekommenderat eftersom det konsumerar mer resurser utan att ge några fördelar.
Sammanfattningsvis
Python är ett av de mest populära programmeringsspråken för att automatisera processer genom att interagera med operativsystemet. En användbar funktion är att kontrollera om en fil eller mapp finns.
De enklaste metoderna för detta är:
- Att öppna och hantera filundantag direkt.
- Att använda funktionen “exists()” från modulerna “os.path” eller “pathlib”.
I den här genomgången har du lärt dig:
- Hur man öppnar en fil och hanterar undantag om den inte existerar.
- Betydelsen av sökvägar.
- Tre olika funktioner i undermodulen “os.path” för att verifiera fil- och mappexistens.
- Att Unix använder snedstreck framåt (/), medan Windows använder snedstreck bakåt (\).
Läs vidare: Vad är en underprocess i Python? [5 Användningsexempel]