Многие программы на 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».