Проверить, существует ли каталог, и при необходимости создать его?
Прямой ответ на этот вопрос заключается в предположении простой ситуации, когда вы не ожидаете, что другие пользователи или процессы будут вмешиваться в ваш каталог:
if not os.path.exists(d):
os.makedirs(d)
или , если создание каталога связано с условиями гонки (то есть, если после проверки путь существует, что-то еще, возможно, уже было сделано), сделайте следующее:
import errno
try:
os.makedirs(d)
except OSError as exception:
if exception.errno != errno.EEXIST:
raise
Но, возможно, еще лучший подход - обойти проблему конкуренции за ресурсы, используя временные каталоги через tempfile
:
import tempfile
d = tempfile.mkdtemp()
Вот основные сведения из онлайн-документа:
mkdtemp(suffix='', prefix='tmp', dir=None)
User-callable function to create and return a unique temporary
directory. The return value is the pathname of the directory.
The directory is readable, writable, and searchable only by the
creating user.
Caller is responsible for deleting the directory when done with it.
Новое в Python 3.5: pathlib.Path
с exist_ok
Появился новый объект Path
(по состоянию на 3.4) с множеством методов, которые можно было бы использовать с путями, один из которых - mkdir
.
(Для контекста, я отслеживаю свою еженедельную репутацию с помощью скрипта. Вот соответствующие части кода из скрипта, которые позволяют мне избежать переполнения стека более одного раза в день для одних и тех же данных.)
Сначала соответствующий импорт:
from pathlib import Path
import tempfile
Теперь нам не нужно иметь дело с os.path.join
- просто соедините части пути с помощью /
:
directory = Path(tempfile.gettempdir()) / 'sodata'
Затем я идемпотентно проверяю, что каталог существует - аргумент exist_ok
отображается в Python 3.5:
directory.mkdir(exist_ok=True)
Вот соответствующая часть документации :
Если exist_ok
истинно, исключения FileExistsError
будут игнорироваться (такое же поведение, как у команды POSIX mkdir -p
), но только если последний компонент пути не является существующим файлом вне каталога.
Вот еще немного сценария - в моем случае я не подвержен состоянию гонки, у меня есть только один процесс, который ожидает, что каталог (или содержащиеся в нем файлы) будет там, и у меня ничего нет пытаюсь удалить каталог.
todays_file = directory / str(datetime.datetime.utcnow().date())
if todays_file.exists():
logger.info("todays_file exists: " + str(todays_file))
df = pd.read_json(str(todays_file))
Path
объекты должны быть приведены к str
, прежде чем другие API, ожидающие пути str
, смогут их использовать.
Возможно, Pandas следует обновить, чтобы принимать экземпляры абстрактного базового класса, os.PathLike
.
В общем, вам может потребоваться учитывать случай, когда в имени файла нет каталога. На моей машине dirname ('foo.txt') дает '', которого не существует и вызывает сбой makedirs ().
если путь существует, нужно не только проверить, является ли он каталогом, а не обычным файлом или другим объектом (многие ответы проверяют это), также необходимо проверить, доступен ли он для записи (я не нашел ответа, который проверял это)
Если вы пришли сюда, чтобы создать родительские каталоги строки пути к файлу
p
, вот мой фрагмент кода:os.makedirs(p[:p.rindex(os.path.sep)], exist_ok=True)