Многие программы на Python нуждаются в навигации по файловой системе для чтения и записи файлов. При этом частой операцией является получение текущего каталога.
Текущую рабочую директорию или каталог сокращенно называют CWD — от англ. «current working directory».
В Python есть два основных модуля, которые можно использовать для доступа к путям файловой системы: модуль os и модуль pathlib.
Модуль os предлагает традиционный подход к получению текущей рабочей директории и работает с путями и файловой системой.
Модуль pathlib — это более новый модуль, который предлагает объектно-ориентированный подход, надежный и кроссплатформенный.
В этой статье мы рассмотрим различные методы получения текущей рабочей директории и работы с ней.
Как получить текущую рабочую директорию
Текущая рабочая директория — это папка, в которой выполняется программа на Python. Она служит точкой отсчета для относительных путей к файлам.
Давайте рассмотрим, как получить доступ к текущей рабочей директории с помощью модулей os и pathlib, и сравним эти два решения.
Использование os.getcwd()
Модуль os позволяет получить доступ к операционной системе компьютера. Функция getcwd() определяет текущий рабочий каталог:
import os cwd = os.getcwd() print(cwd) # Результат: # /Users/sg/Documents/GitHub/datacamp
На выходе вы увидите путь к директории, содержащей скрипт. Формат пути зависит от операционной системы. Приведенный выше вывод относится к операционным системам POSIX, таким как Linux, Unix и macOS.
Тот же путь в системе Windows будет выглядеть следующим образом:
C:\Users\sg\Documents\GitHub\datacamp
Значение, возвращаемое os.getcwd(), представляет собой строку:
print(type(cwd)) # Результат: # <class 'str'>
Поэтому для работы с этим путем нам нужно использовать строковые методы и другие строковые операции.
Использование pathlib.Path.cwd()
В Python 3.4 появился модуль pathlib, который предлагает объектно-ориентированный подход к доступу и манипулированию путями к файлам. Основным классом в pathlib является Path, который мы можем импортировать перед получением текущей рабочей директории:
from pathlib import Path cwd = Path.cwd() print(cwd) # Результат: # /Users/sg/Documents/GitHub/datacamp
Вывод Path.cwd() похож на значение, возвращаемое os.getcwd(). Но Path.cwd() возвращает не строку. Мы можем убедиться в этом, распечатав тип возвращаемого объекта или выведя его официальное строковое представление с помощью repr():
print(type(cwd))
print(repr(cwd))
# Результат:
# <class 'pathlib.PosixPath'>
# PosixPath('/Users/sg/Documents/GitHub/datacamp')
На компьютере под управлением Windows функция Path.cwd() возвращает объект WindowsPath.
Объекты PosixPath и WindowsPath предоставляют схожую функциональность, позволяя создавать кроссплатформенные программы. Вот некоторые из атрибутов этих объектов:
print(cwd.parent) print(cwd.name) # Результат: # /Users/sg/Documents/GitHub # datacamp
По возможности лучше использовать модуль pathlib: он более современный и упрощает работу с путями.
Работа с текущей директорией
В программах на Python часто возникает необходимость манипулировать путем, например, чтобы сохранить файл во вложенной папке. Предположим, нам нужно создать новый подкаталог в текущей рабочей директории и сохранить в нем текстовый файл.
Использование модуля os
Функция getcwd() в модуле os возвращает строку. Поэтому, чтобы изменить путь, можно вручную изменить эту строку. Однако необходимые изменения зависят от операционной системы, поскольку в разных системах используются разные форматы путей. Лучшим вариантом является использование os.path.join():
import os cwd = os.getcwd() output_path = os.path.join(cwd, "testing_os") print(output_path) # Результат: # /Users/sg/Documents/GitHub/datacamp/testing_os
Путь, который возвращает os.path.join(), имеет правильный формат для используемой операционной системы. В результате возвращается строка с новым путем. Мы можем проверить, не существует ли уже такая вложенная директория, с помощью функции os.path.exists(), которая возвращает булево значение:
print(os.path.exists(output_path)) # Результат: # False
False в выводе показывает, что путь, представленный output_path, еще не существует. Модуль os предоставляет инструменты для его создания. Функция os.mkdir() создает новый каталог:
os.mkdir(output_path) print(os.path.exists(output_path)) # Результат: # True
Теперь новый подкаталог существует и в нем могут быть сохранены новые файлы:
output_file = os.path.join(output_path, "test.txt")
with open(output_file, "w") as file:
file.write("Testing path modification with the 'os' module")
Переменная output_file содержит имя желаемого выходного файла с полным путем. Этот текстовый файл создается во вложенной папке /testing_os в текущей рабочей директории.
Мы также можем перечислить все элементы в папке с помощью os.listdir():
for item in os.listdir(output_path):
print(item)
# Результат:
# test.txt
Функция os.listdir() возвращает список со всеми элементами в каталоге. Этот код итерирует этот список для отображения каждого файла или папки в отдельной строке. В этом примере каталог содержит один текстовый файл.
Примечание редакции: также рекомендуем статью «Как проверить существование файла с помощью Python».
Использование модуля pathlib
Более новый модуль pathlib также предоставляет инструменты для создания новых путей. Этот модуль использует оператор прямой косой черты / для объединения элементов в путь. Это тот же оператор, который используется для разделения числовых типов данных, а также символ, используемый в файловых путях в операционных системах POSIX.
Давайте создадим новый путь и проверим, не существует ли он уже:
from pathlib import Path cwd = Path.cwd() output_path = cwd / "testing_pathlib" print(output_path) print(Path.exists(output_path)) # Результат: # /Users/sg/Documents/GitHub/datacamp/testing_pathlib # False
Класс Path имеет собственный метод .mkdir() для создания новой директории:
Path.mkdir(output_path) print(Path.exists(output_path)) # Результат: #True
Поскольку output_path — это объект PosixPath или WindowsPath, мы можем использовать оператор прямой косой черты в любом месте, чтобы создать новый путь:
with open(output_path / "test.txt", "w") as file:
file.write("Testing path modification with the 'pathlib' module")
Новый текстовый файл создается в папке /testing_pathlib.
Для перебора всех элементов в директории можно использовать метод Path .iterdir():
for item in Path.iterdir(output_path):
print(item)
# Результат:
# /Users/sg/Documents/GitHub/datacamp/testing_pathlib/test.txt
Как и в других инструментах pathlib, возвращаемое значение не является строкой. Это объект PosixPath или WindowsPath. Мы можем использовать атрибут .name для отображения имени файла или папки без полного пути:
for item in Path.iterdir(output_path):
print(item.name)
# Результат:
# test.txt
В то время как os.listdir() возвращает список, pathlib.Path.iterdir() возвращает объект-генератор:
print(Path.iterdir(cwd)) # Результат: # <generator object Path.iterdir at 0x1036b2c20>
Такое поведение соответствует лучшим практикам современного Python, поскольку итераторы и генераторы более эффективны в определенных ситуациях.
Изменение текущей рабочей директории (CWD)
Также можно изменить текущий рабочий каталог прямо из программы на Python с помощью os.chdir(). Поскольку эта операция не связана напрямую с путем, в pathlib нет альтернативной версии. Однако мы все равно можем использовать объекты pathlib.Path в качестве аргументов:
import os from pathlib import Path cwd = Path.cwd() print(cwd) os.chdir(cwd.parent) cwd = Path.cwd() print(cwd) # Результат: # /Users/sg/Documents/GitHub/datacamp # /Users/sg/Documents/GitHub
Теперь рабочий каталог изменился. Мы также можем использовать cwd.parent.resolve(), чтобы убедиться в правильности обработки любых символических ссылок. Аргументом в os.chdir() также может быть строка, например, пути, возвращаемые функциями модуля os.
Будьте осторожны, изменяя рабочую директорию внутри программы, чтобы не допустить неожиданного поведения.
Лучшие практики и советы
Вот несколько лучших практик и советов при работе с путями в Python:
- В новых проектах используйте pathlib. Это интуитивно понятный и объектно-ориентированный подход к работе с путями.
- Следите за межплатформенной совместимостью. Используйте os.path.join() или оператор прямой косой черты в pathlib для создания путей, которые будут работать в различных операционных системах.
- Проверяйте существование путей. Всегда проверяйте, не существует ли уже такой путь, прежде чем проводить с ним какие-либо манипуляции. В этом вам помогут
os.psth.exists()иPath.Exists(). - Не меняйте текущую директорию без необходимости. Чем меньше случаев смены рабочей директории, тем меньше вероятность неожиданного поведения программы и проще поддержка кода.
- Реализуйте обработку ошибок. Используйте блоки try-except для управления ошибками в файловых операциях и предоставления осмысленных сообщений об ошибках.
- Ставьте безопасность на первое место. При конструировании путей проверяйте пользовательский ввод, чтобы предотвратить атаки на директории.
Заключение
Навигация по файловой системе и манипулирование путями к файлам — частое требование во многих программах на Python. Модуль os предоставляет традиционные функции для решения этих задач, а модуль pathlib предлагает более современный, объектно-ориентированный подход. Использование pathlib не только упрощает многие операции, но и гарантирует, что ваш код останется кроссплатформенным и легко читаемым.
Независимо от того, поддерживаете ли вы существующую кодовую базу, использующую os, или начинаете новый проект, в котором можно использовать pathlib, знакомство с обоими модулями и их возможностями обеспечит вам гибкость и уверенность в управлении путями в любом проекте на Python.
Перевод статьи «How to Get the Current Directory in Python».

