Как найти, если каталог существует в Python

1140

В osмодуле в Python есть способ узнать, существует ли каталог, что-то вроде:

>>> os.direxists(os.path.join(os.getcwd()), 'new_folder')) # in pseudocode
True/False
David542
источник
8
Предупреждение: ответ с наивысшей оценкой может быть подвержен условиям гонки. Возможно, вы захотите выполнить os.statвместо этого, чтобы увидеть, существует ли каталог и является ли каталог одновременно.
d33tah
1
@ d33tah Возможно, у вас есть хорошая мысль, но я не вижу способа, os.statчтобы отличить каталог от файла. Он возникает, OSErrorкогда путь неверен, независимо от того, файл это или каталог. Кроме того, любой код после проверки также подвержен условиям гонки.
Томаш Зато - Восстановить Монику
4
@ TomášZato: это приводит к выводу, что это безопасно, просто выполнять операции и обрабатывать ошибки.
августа
2
@ David542 Я добавил уточняющий случай с тестами на точность для «isdir» «существует». Я думаю, вы бы научились чему-нибудь сейчас. Но это может осветить новых людей.
GeoStoneMarten

Ответы:

1729

Вы ищете os.path.isdir, или os.path.existsесли вам все равно, файл это или каталог.

Пример:

import os
print(os.path.isdir("/home/el"))
print(os.path.exists("/home/el/myfile.txt"))
phihag
источник
4
@syedrakib Хотя круглые скобки могут использоваться для обозначения объекта, который можно вызывать, в Python это бесполезно, поскольку даже классы могут вызываться. Кроме того, функции являются первоклассными значениями в Python, и вы можете использовать их без обозначения в скобках, как вexisting = filter(os.path.isdir(['/lib', '/usr/lib', '/usr/local/lib'])
phihag
10
Вы можете передавать функции другим функциям, например map, но в общем случае вы вызываете функции с аргументами и круглыми скобками. Также в вашем примере есть опечатка. по-видимому, вы имеете в виду filter(os.path.isdir, ['/lib', '/usr/lib', '/usr/local/lib']).
hughdbrown
4
Кроме того, есть, os.path.isfile(path)если вы заботитесь только о том, является ли это файл.
Николас
2
Имейте в виду, что на некоторых платформах они возвращают false, если файл / каталог существует, но также возникает ошибка разрешения на чтение.
Cowlinator
74

Так близко! os.path.isdirвозвращается, Trueесли вы передаете имя каталога, который существует в настоящее время. Если он не существует или не является каталогом, он возвращается False.

Кирк Штраузер
источник
70

Python 3.4 вводится в pathlibмодуле в стандартную библиотеку, которая обеспечивает ориентированный подход объекта для обработки файловой системы путей. В is_dir()и exists()методы в Pathобъекте могут быть использованы для ответа на вопрос:

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

Пути (и строки) могут быть объединены вместе с /оператором:

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 также доступен на Python 2.7 через модуль pathlib2 на PyPi.

joelostblom
источник
Некоторое объяснение было бы полезно. Почему ты делаешь " p / 'bin' / 'vim'?
Натан
1
@frank Я немного уточнил вторую часть ответа.
Джоелостблом
34

Да, используйте os.path.exists().

aganders3
источник
23
Это не проверяет, что путь является каталогом.
Кирк Штраузер
7
Хороший звонок. Другие указали, что это os.path.isdirбудет сделано.
aganders3
3
Если вы понимаете, что это не отвечает на вопрос, почему бы вам не удалить ответ?
3
@CamilStaps Этот вопрос был просмотрен 354000 раз (сейчас). Ответы здесь не только для ОП, они для всех, кто мог бы прийти сюда по любой причине. Ответ aganders3 уместен, даже если он напрямую не решает проблему OP.
Габриэль
4
@ Габриэль, тогда в ответе должно быть ясно, что это на самом деле делает.
21

Мы можем проверить с помощью 2 встроенных функций

os.path.isdir("directory")

Это даст логическое значение true, указанный каталог доступен.

os.path.exists("directoryorfile")

Это даст логическое значение true, если указанный каталог или файл доступен.

Проверить, является ли путь каталогом;

os.path.isdir("directorypath")

даст логическое значение true, если путь является каталогом

Вивек Анантан
источник
2
Это полностью излишне с более старым, лучшим ответом.
Дэвис Херринг
10

Как в:

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

Вероятно, бросить в, os.path.isdir(...)чтобы быть уверенным.

ALG
источник
10

Просто чтобы предоставить os.statверсию (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
Тайлер А.
источник
7

ОС предоставляет вам множество этих возможностей:

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 сгенерирует исключение, если путь ввода неверен.

dputros
источник
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
источник
6
В Python есть встроенные функции для создания каталогов, поэтому лучше использовать os.makedirs('mydir')вместо нихos.system(...)
gizzmole
9
Вы печатаете, что «новый каталог создан», но вы этого не знаете. Что делать, если у вас нет прав на создание каталога? Вы бы напечатали «новый каталог создан», но это не будет правдой. Будет ли это.
Войцех Якубас
4

Есть удобный Unipathмодуль.

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

Другие связанные вещи, которые вам могут понадобиться:

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

Вы можете установить его используя pip:

$ pip3 install unipath

Это похоже на встроенный pathlib. Разница в том, что он обрабатывает каждый путь как строку ( Pathявляется подклассом str), поэтому, если какая-то функция ожидает строку, вы можете легко передать ейPath объект без необходимости преобразовывать его в строку.

Например, это прекрасно работает с Django и settings.py :

# settings.py
BASE_DIR = Path(__file__).ancestor(2)
STATIC_ROOT = BASE_DIR + '/tmp/static'
Макс Малыш
источник
4

Вы также можете создать каталог, если его там нет.

Источник , если он все еще там на SO.

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

На Python ≥ 3.5 используйте pathlib.Path.mkdir:

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

Для более старых версий Python я вижу два ответа с хорошими качествами, каждый с небольшим недостатком, поэтому я сделаю это:

Попробуйте os.path.existsи рассмотрите os.makedirsдля создания.

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

Как отмечено в комментариях и в других местах, существует условие состязания - если каталог создается между вызовами os.path.existsи os.makedirsвызовами, os.makedirsпроизойдет сбой с помощью OSError. К сожалению, общий поиск OSErrorи продолжение не являются надежными, так как они будут игнорировать сбой при создании каталога из-за других факторов, таких как недостаточные разрешения, полный диск и т. Д.

Один из вариантов - перехватить OSErrorи изучить встроенный код ошибки (см. Существует ли кроссплатформенный способ получения информации из Python OSError ):

import os, errno

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

В качестве альтернативы, может быть второй os.path.exists , но предположим, что другой создал каталог после первой проверки, а затем удалил его до второй проверки - нас все еще можно обмануть.

В зависимости от приложения опасность одновременных операций может быть больше или меньше опасности других факторов, таких как права доступа к файлам. Разработчик должен знать больше о конкретном разрабатываемом приложении и его ожидаемой среде, прежде чем выбирать реализацию.

Современные версии Python немного улучшают этот код, предоставляя FileExistsError(в версии 3.3+ ) ...

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

... и позволяя ключевому аргументу os.makedirsвызыватьсяexist_ok (в 3.2+).

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.
Натан
источник
0

Две вещи

  1. проверить, существует ли каталог?
  2. если нет, создайте каталог (необязательно).
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")
Удай Киран
источник