Sjekk om fil eller mappe finnes i Python: 7 enkle metoder


Utforske fil- og katalogeksistens i Python

Pythons standardbibliotek tilbyr et bredt spekter av verktøy som utviklere trenger for å løse ulike utfordringer. I denne veiledningen skal vi se på ulike metoder for å bekrefte om en fil eller katalog eksisterer, ved kun å bruke innebygde moduler i Python.

Å kunne verifisere plasseringen av en fil eller et skript er viktig for alle kommandolinjeverktøy (CLI). Et program kan bli ubrukelig hvis en bestemt fil ikke er tilgjengelig når det kjøres.

I denne artikkelen vil du oppdage raske og effektive måter å sjekke om en fil eller mappe finnes i Python.

Før du begynner

Før du prøver noen av kommandoene nedenfor, må du forsikre deg om at Python 3 er installert på systemet ditt. Åpne terminalen og skriv denne kommandoen:

python --version
# Python 3.9.5, mitt resultat

Dersom du har en 2.x versjon, må du bruke kommandoen «python3». Hvis du ikke har Python 3 installert, kan du sjekke vår Python-installasjonsveiledning.

Vi skal bruke noen testfiler gjennom denne veiledningen, så vennligst lag følgende filer:

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

Disse kommandoene skaper en fil å eksperimentere med, en testkatalog og en annen fil inne i testkatalogen. Filene kan være tomme, da vi ikke trenger å lese innholdet.

Merk: Hvis du bruker Windows, kan du opprette denne enkle filstrukturen ved hjelp av en grafisk filbehandler.

Til slutt skal vi benytte oss av Ipython som vårt interaktive Python-skall, som tilbyr et brukervennlig grensesnitt. Dette er valgfritt, men anbefalt.

pip install ipython

Etter dette, vil du kunne bruke et forbedret Python-skall ved å skrive inn «ipython».

Nå er du klar til å dykke ned i forskjellige metoder for å verifisere om en mappe eller fil eksisterer i Python.

«Prøv, Åpne, og Håndter Unntak» Metoden

Dette er en av de mest grunnleggende tilnærmingene. Når du forsøker å åpne en fil som ikke eksisterer, vil Python generere en FileNotFoundError.

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

Vi kan bruke dette i vår fordel, ved å håndtere unntaket som oppstår når filen vi leter etter ikke finnes.

In [2]: try:
   ...:     file = open('im-not-here.txt')
   ...:     print(file) # Filhåndterer
   ...:     file.close()
   ...: except FileNotFoundError:
   ...:     print('Beklager, filen vi leter etter finnes ikke')
   ...:     exit()
   ...: 
Beklager, filen vi leter etter finnes ikke

I koden ovenfor gir vi en tilpasset melding og avslutter programmet hvis filen ikke eksisterer.

Legg merke til hvordan exit()-funksjonen kun kjøres hvis et unntak oppstår. La oss se hva som skjer når filen vi søker etter faktisk finnes.

In [2]: try:
   ...:     file = open('testfile.txt')
   ...:     print(file) # Filhåndterer
   ...:     file.close()
   ...: except FileNotFoundError:
   ...:     print('Beklager, filen vi leter etter finnes ikke')
   ...:     exit()
   ...: 
<_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>

Husk at vi lukker filen rett etter at vi har åpnet den. Dette er en god praksis ifølge Pythons dokumentasjon.

Å kalle file.write() uten å bruke «with»-kommandoen eller kalle file.close() kan medføre at argumentene til file.write() ikke skrives fullstendig til disk, selv om programmet avsluttes.

Selv om vi ikke skriver til filen, anbefales det sterkt å lukke den fordi det kan forårsake ytelsesproblemer.

Hvis vi ikke vil lukke filen selv, kan vi bruke «with» kontekstbehandling. Den håndterer tildeling og frigjøring av ressurser nøyaktig, og vi slipper å lukke filen manuelt.

In [3]: try:
   ...:     with open('testfile.txt') as file:
   ...:         print(file)
   ...:         # Ingen grunn til å lukke filen
   ...: except FileNotFoundError:
   ...:     print('Beklager, filen vi leter etter finnes ikke')
   ...:     exit()
   ...: 
   ...: 
<_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>

Denne tilnærmingen er svært nyttig når du arbeider med å skrive til filer, men er ikke den mest effektive hvis vi kun skal sjekke om en fil eksisterer. La oss utforske andre muligheter for å oppnå dette.

os.path.exists()

os-modulen tilbyr diverse funksjoner for å samhandle med operativsystemet. For å bekrefte eksistensen av en fil eller mappe, kan vi bruke funksjonen path.exists(), som tar banen til filen eller katalogen som argument. Den returnerer en boolsk verdi basert på om banen eksisterer.

Merk: En bane definerer den unike lokasjonen til en fil eller katalog i et filsystem.

I Python inneholder os.path undermodulen funksjoner som er spesielt utviklet for å håndtere filbaner. Alle disse funksjonene aksepterer baneargumenter som strenger eller bytes, og du kan velge å jobbe med absolutte baner, for eksempel:

/home/daniel/.bashrc

Eller med relative baner, avhengig av mappen der du kjører skriptet:

.bashrc
# Når skriptet kjøres fra hjemmekatalogen

Her er noen eksempler på bruk av os.path.exists()-funksjonen, som kjøres i mappen der testfilene er plassert:

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, returnerer den «True» når vi tester med filen testfile.txt og mappen testdirectory, og «False» når filen ikke eksisterer.

os.path.isfile()

Hvis du kun ønsker å bekrefte om en fil (ikke en mappe) eksisterer, kan du bruke funksjonen 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

Merk: I UNIX avsluttes alle mapper med en skråstrek (/), mens vi bruker en omvendt skråstrek (\) i Windows.

I koden ovenfor returnerer isfile()-funksjonen False ved to anledninger, la oss se hvorfor:

  • testdirectory/ er en mappe, og derfor regnes den ikke som en fil. Dette stemmer ikke helt, siden i Linux er alt en filbeskrivelse, men Python behandler mapper annerledes bare for å gjøre det enklere (hvis du prøver å åpne en mappe, vil du få en IsADirectoryError).
  • i-dont-even-exist refererer til en fil som ikke eksisterer.

os.path.isdir()

Dersom du vil bekrefte at en mappe finnes på riktig sted, bør du bruke os.path.isdir()-funksjonen, som bare returnerer «True» hvis den gitte banen peker til en mappe.

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

Merk at eksemplene ovenfor returnerer «False» selv når banen peker til en eksisterende fil.

Glob

Glob-modulen tilbyr funksjoner for å jobbe med Unix-lignende skallmønstre (derfor fungerer den ikke optimalt i Windows). For å sjekke om en fil samsvarer med et mønster i gjeldende mappe, kan du bruke funksjonen 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 ovenfor er mønsteret som sendes til glob-funksjonen en vanlig streng som representerer banen til testfilen og mappen. Siden begge banene eksisterer, returnerer funksjonen en liste med tilsvarende banenavn.

Merk: Hvis mønsteret ikke stemte, ville du fått en tom liste.

Siden vi kan overføre mønstre til glob-funksjonen, la oss teste ut noen av de viktigste fordelene med denne tilnærmingen.

Koden nedenfor finner alle filbaner med filtypen .txt og .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']

Bruke Path-klassen

Path-klassen gir en utmerket måte å jobbe med baner på, siden den tilbyr et rent grensesnitt for å arbeide med filbaner som objekter.

Viktigst av alt har Path-instanser alle metodene du trenger for å få informasjon om en spesifikk bane. Dette inkluderer lignende funksjoner som de vi har sett på tidligere.

Merk: Du trenger Python 3.4 eller nyere for å bruke pathlib-biblioteket.

Path-metodene du kan bruke:

Bekrefte om en bane eksisterer

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

Fungerer på samme måte som os.path.exists().

Bekrefte om banen peker til en fil

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

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

Tilsvarer os.path.isfile().

Bekrefte om banen peker til en mappe

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

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

Tilsvarer os.path.isdir().

Delprosess

Hvis du foretrekker å bruke underprosessmoduler, er det verdt å vurdere dette alternativet. Du kan undersøke om en fil eller mappe eksisterer ved å bruke test-kommandoen.

Merk: test-kommandoen fungerer kun i Unix.

Følgende testflagg vil være nyttige:

  • test -e: Bekreft om en bane eksisterer.
  • test -f: Bekreft om en fil eksisterer.
  • test-d: Bekreft om en mappe eksisterer.

Hvis du er interessert i flere testflagg, kan du lese manualen ved å kjøre:

man test

Bekrefte en bane med delprosess:

Koden nedenfor finner ut om en bane eksisterer ved å sammenligne returkoden til underprosessen med 0.

I Linux vil en prosess returnere null hvis den ble fullført uten problemer, og en annen kode hvis det oppsto et problem.

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 første linje importerer vi underprosessmodulen, deretter bruker vi run-funksjonen for å få returkoden.

Bekrefte eksistensen av en fil med delprosess

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

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

Bekrefte en mappe med delprosess:

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

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

Det er ikke anbefalt å bruke denne metoden siden den bruker flere ressurser, og det gir ingen klare fordeler.

Oppsummering

Python er et populært programmeringsspråk for å automatisere prosesser gjennom samhandling med operativsystemet. En nyttig ting du kan gjøre er å undersøke om en fil eller mappe eksisterer.

De enkleste måtene å gjøre dette på er:

  • Å åpne en fil og håndtere unntak i samme operasjon.
  • Å bruke exists()-funksjonen fra os.path- eller pathlib-modulene.

I denne veiledningen har du lært:

  • Hvordan åpne en fil og håndtere unntak hvis den ikke eksisterer.
  • Betydningen av stier.
  • 3 ulike funksjoner os.path-undermodulen tilbyr for å sjekke eksistensen av en fil eller mappe.
  • At Unix bruker fremover-skråstreker (/), mens Windows bruker bakover-skråstreker ().

Neste lesning: Hva er en underprosess i Python? [5 Brukseksempler]