Jak sprawdzić, czy katalog istnieje w Pythonie

1135

W osmodule w Pythonie jest sposób na sprawdzenie, czy istnieje katalog, coś w rodzaju:

>>> os.direxists(os.path.join(os.getcwd()), 'new_folder')) # in pseudocode
True/False
David542
źródło
8
Słowo ostrzeżenia - najwyżej oceniana odpowiedź może być podatna na warunki wyścigowe. Możesz os.statzamiast tego wykonać , aby sprawdzić, czy katalog istnieje i jest katalogiem w tym samym momencie.
d33tah
1
@ d33tah Być może masz rację, ale nie widzę sposobu na odróżnienie os.statkatalogu od pliku. Podnosi się, OSErrorgdy ścieżka jest nieprawidłowa, bez względu na to, czy jest to plik, czy katalog. Ponadto każdy kod po sprawdzeniu jest również podatny na warunki wyścigu.
Tomáš Zato - Przywróć Monikę
4
@ TomášZato: co prowadzi do wniosku, że bezpiecznie jest po prostu wykonać operację i obsługiwać błędy.
d33tah
2
@ David542 Dodałem przypadek wyjaśniający z testami dokładności dla „isdir” „istnieje”. Myślę, że nauczyłbyś się teraz wszystkiego. Ale może oświetlić nowych ludzi.
GeoStoneMarten,

Odpowiedzi:

1727

Szukasz os.path.isdirlub os.path.existsnie przejmujesz się, czy jest to plik, czy katalog.

Przykład:

import os
print(os.path.isdir("/home/el"))
print(os.path.exists("/home/el/myfile.txt"))
phihag
źródło
4
@syedrakib Chociaż można użyć nawiasów, aby wskazać, że obiekt można wywoływać, nie jest to przydatne w Pythonie, ponieważ można wywoływać nawet klasy. Ponadto funkcje są pierwszorzędnymi wartościami w Pythonie i można ich używać bez zapisu w nawiasach, na przykład wexisting = filter(os.path.isdir(['/lib', '/usr/lib', '/usr/local/lib'])
phihag
10
Możesz przekazać funkcje do innych funkcji, takich jak map, ale w ogólnym przypadku wywołujesz funkcje z argumentami i nawiasami. W twoim przykładzie jest też literówka. prawdopodobnie masz na myśli filter(os.path.isdir, ['/lib', '/usr/lib', '/usr/local/lib']).
hughdbrown
4
Jest również, os.path.isfile(path)jeśli zależy ci tylko na tym, czy jest to plik.
Nicholas
2
Należy pamiętać, że na niektórych platformach zwracają wartość false, jeśli plik / katalog istnieje, ale występuje również błąd uprawnień do odczytu.
cowlinator,
73

Tak blisko! os.path.isdirzwraca, Truejeśli podasz nazwę katalogu, który obecnie istnieje. Jeśli nie istnieje lub nie jest katalogiem, zwraca False.

Kirk Strauser
źródło
70

Python 3.4 wprowadziła ten pathlibmoduł w bibliotece standardowej, która zapewnia zorientowaną podejścia obiektowego do ścieżek uchwyt systemu plików. Te is_dir()i exists()metody z Pathobiektu mogą być wykorzystane, aby odpowiedzieć na pytanie:

In [1]: from pathlib import Path

In [2]: p = Path('/usr')

In [3]: p.exists()
Out[3]: True

In [4]: p.is_dir()
Out[4]: True

Ścieżki (i ciągi) można łączyć razem z /operatorem:

In [5]: q = p / 'bin' / 'vim'

In [6]: q
Out[6]: PosixPath('/usr/bin/vim') 

In [7]: q.exists()
Out[7]: True

In [8]: q.is_dir()
Out[8]: False

Pathlib jest również dostępny w Pythonie 2.7 za pośrednictwem modułu pathlib2 w PyPi.

joelostblom
źródło
Pomocne byłoby jakieś wyjaśnienie. Dlaczego to robisz p / 'bin' / 'vim'? ”
Nathan
1
@frank Opracowałem nieco drugą część odpowiedzi.
joelostblom
34

Tak, użyj os.path.exists().

agandery3
źródło
23
To nie sprawdza, czy ścieżka jest katalogiem.
Kirk Strauser,
7
Dobra decyzja. Inni wskazali, że os.path.isdirto osiągnie.
aganders3
3
Jeśli rozumiesz, że to nie odpowiada na pytanie, dlaczego nie usuniesz odpowiedzi?
3
@CamilStaps To pytanie było oglądane 354000 razy (do tej pory). Odpowiedzi tutaj są nie tylko dla OP, są dla każdego, kto mógłby tu przyjechać z jakiegokolwiek powodu. Odpowiedź aganders3 jest trafna, nawet jeśli nie rozwiązuje bezpośrednio problemu OP.
Gabriel
4
@Gabriel, w odpowiedzi należy wyjaśnić, co to właściwie robi.
21

Możemy to sprawdzić za pomocą 2 wbudowanych funkcji

os.path.isdir("directory")

Da logiczną wartość true, określony katalog jest dostępny.

os.path.exists("directoryorfile")

Daje boolead true, jeśli określony katalog lub plik jest dostępny.

Aby sprawdzić, czy ścieżka jest katalogiem;

os.path.isdir("directorypath")

da wartość logiczną true, jeśli ścieżka jest katalogiem

Vivek Ananthan
źródło
2
Jest to całkowicie zbędne w przypadku starszych, najlepszych odpowiedzi.
Davis Herring
10

Jak w:

In [3]: os.path.exists('/d/temp')
Out[3]: True

Prawdopodobnie wrzuć to os.path.isdir(...)dla pewności.

AlG
źródło
10

Wystarczy podać os.statwersję (python 2):

import os, stat, errno
def CheckIsDir(directory):
  try:
    return stat.S_ISDIR(os.stat(directory).st_mode)
  except OSError, e:
    if e.errno == errno.ENOENT:
      return False
    raise
Tyler A.
źródło
7

os zapewnia wiele z tych możliwości:

import os
os.path.isdir(dir_in) #True/False: check if this is a directory
os.listdir(dir_in)    #gets you a list of all files and directories under dir_in

listdir zgłosi wyjątek, jeśli ścieżka wejściowa jest nieprawidłowa.

dputros
źródło
5
#You can also check it get help for you

if not os.path.isdir('mydir'):
    print('new directry has been created')
    os.system('mkdir mydir')
JoboFive
źródło
6
python ma wbudowane funkcje do tworzenia katalogów, więc lepiej użyć os.makedirs('mydir')zamiastos.system(...)
gizzmole
9
Drukujesz, że „utworzono nowy katalog”, ale nie wiesz o tym. Co zrobić, jeśli nie masz uprawnień do utworzenia katalogu? Wydrukowałbyś „utworzono nowy katalog”, ale nie byłoby to prawdą. Zrobiłbym to.
Wojciech Jakubas
4

Jest wygodny Unipathmoduł.

>>> from unipath import Path 
>>>  
>>> Path('/var/log').exists()
True
>>> Path('/var/log').isdir()
True

Inne powiązane rzeczy, których możesz potrzebować:

>>> Path('/var/log/system.log').parent
Path('/var/log')
>>> Path('/var/log/system.log').ancestor(2)
Path('/var')
>>> Path('/var/log/system.log').listdir()
[Path('/var/foo'), Path('/var/bar')]
>>> (Path('/var/log') + '/system.log').isfile()
True

Możesz go zainstalować za pomocą pipa:

$ pip3 install unipath

Jest podobny do wbudowanego pathlib. Różnica polega na tym, że traktuje każdą ścieżkę jako ciąg ( Pathjest podklasą str), więc jeśli jakaś funkcja oczekuje ciągu, możesz z łatwością przekazać mu Pathobiekt bez konieczności konwertowania go na ciąg.

Na przykład działa to świetnie z Django i settings.py:

# settings.py
BASE_DIR = Path(__file__).ancestor(2)
STATIC_ROOT = BASE_DIR + '/tmp/static'
Max Malysh
źródło
4

Możesz także utworzyć katalog, jeśli go tam nie ma.

Źródło , jeśli nadal istnieje na SO.

================================================== ===================

W Pythonie ≥ 3.5 użyj pathlib.Path.mkdir:

from pathlib import Path
Path("/my/directory").mkdir(parents=True, exist_ok=True)

W przypadku starszych wersji Pythona widzę dwie odpowiedzi o dobrych cechach, każda z małą wadą, więc przyjmuję to:

Spróbuj os.path.existsi zastanów się os.makedirsnad stworzeniem.

import os
if not os.path.exists(directory):
    os.makedirs(directory)

Jak zauważono w komentarzach i gdzie indziej, istnieje warunek wyścigu - jeśli katalog zostanie utworzony między połączeniami os.path.existsi, os.makedirspołączenie os.makedirszakończy się niepowodzeniem OSError. Niestety łapanie OSErrori kontynuowanie koców nie jest niezawodne, ponieważ zignoruje niepowodzenie tworzenia katalogu z powodu innych czynników, takich jak niewystarczające uprawnienia, pełny dysk itp.

Jedną z opcji byłoby przechwycenie OSErrori sprawdzenie osadzonego kodu błędu (zobacz Czy istnieje wieloplatformowy sposób uzyskiwania informacji z OSError Pythona ):

import os, errno

try:
    os.makedirs(directory)
except OSError as e:
    if e.errno != errno.EEXIST:
        raise

Alternatywnie może istnieć sekunda os.path.exists, ale załóżmy, że inny utworzył katalog po pierwszym sprawdzeniu, a następnie usunął go przed drugim - nadal możemy się oszukać.

W zależności od aplikacji niebezpieczeństwo równoczesnych operacji może być większe lub mniejsze niż niebezpieczeństwo stwarzane przez inne czynniki, takie jak uprawnienia do plików. Deweloper musiałby dowiedzieć się więcej o konkretnej aplikacji i jej oczekiwanym środowisku przed wybraniem implementacji.

Nowoczesne wersje Pythona znacznie poprawiają ten kod, zarówno poprzez ujawnienie FileExistsError(w wersji 3.3 +) ...

try:
    os.makedirs("path/to/directory")
except FileExistsError:
    # directory already exists
    pass

... i pozwalając argument słowa kluczowego dla os.makedirsnazywanyexist_ok (w 3.2 lub nowszym).

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.
Nathan
źródło
0

Dwie rzeczy

  1. sprawdzić, czy katalog istnieje?
  2. jeśli nie, utwórz katalog (opcjonalnie).
import os
dirpath = "<dirpath>" # Replace the "<dirpath>" with actual directory path.

if os.path.exists(dirpath):
   print("Directory exist")
else: #this is optional if you want to create a directory if doesn't exist.
   os.mkdir(dirpath):
   print("Directory created")
Uday Kiran
źródło