Как найти каталог python

The pathlib module, introduced in Python 3.4 (PEP 428 — The pathlib module — object-oriented filesystem paths), makes the path-related experience much much better.

pwd

/home/skovorodkin/stack

tree

.
└── scripts
    ├── 1.py
    └── 2.py

In order to get the current working directory, use Path.cwd():

from pathlib import Path

print(Path.cwd())  # /home/skovorodkin/stack

To get an absolute path to your script file, use the Path.resolve() method:

print(Path(__file__).resolve())  # /home/skovorodkin/stack/scripts/1.py

And to get the path of a directory where your script is located, access .parent (it is recommended to call .resolve() before .parent):

print(Path(__file__).resolve().parent)  # /home/skovorodkin/stack/scripts

Remember that __file__ is not reliable in some situations: How do I get the path of the current executed file in Python?.


Please note, that Path.cwd(), Path.resolve() and other Path methods return path objects (PosixPath in my case), not strings. In Python 3.4 and 3.5 that caused some pain, because open built-in function could only work with string or bytes objects, and did not support Path objects, so you had to convert Path objects to strings or use the Path.open() method, but the latter option required you to change old code:

File scripts/2.py

from pathlib import Path

p = Path(__file__).resolve()

with p.open() as f: pass
with open(str(p)) as f: pass
with open(p) as f: pass

print('OK')

Output

python3.5 scripts/2.py

Traceback (most recent call last):
  File "scripts/2.py", line 11, in <module>
    with open(p) as f:
TypeError: invalid file: PosixPath('/home/skovorodkin/stack/scripts/2.py')

As you can see, open(p) does not work with Python 3.5.

PEP 519 — Adding a file system path protocol, implemented in Python 3.6, adds support of PathLike objects to the open function, so now you can pass Path objects to the open function directly:

python3.6 scripts/2.py

OK

Если вы запускаете скрипт C:Scriptsscript.py из D:work папки:

D:work> py C:Scriptsscript.py

то:

  • D:work — это текущая рабочая директория на момент старта скрипта. open('file.txt') будет пытаться открыть D:workfile.txt файл
  • C:Scripts — это директория со скриптом.

Текущая рабочая директория

Текущая рабочая директория возвращается os.getcwd() функцией, где CWD это Current Working Directory («текущая рабочая директория»). os.getcwdb() возвращает путь в виде байт. Происхождение функции от POSIX getcwd(3). Другие способы могут вернуть разные результаты в зависимости от настроек доступа промежуточных директорий, общей длины (от платформы зависит) итд—не изобретайте своих способов, если не осознаёте всех последствий возможного изменения в поведении функции. Также нетрадиционные способы получения рабочей директории могут ухудшить читаемость другими Питон-программистами. Из The Zen of Python
:

There should be one— and preferably only one —obvious way to do it.

По умолчанию относительные пути используют именно эту директорию, поэтому явно вызывать os.getcwd() редко нужно. Например, open('file.txt') вызов открывает файл 'file.txt' в текущей директории. Если необходимо передать полный путь в виде строки, то можно использовать os.path.abspath('file.txt')getcwd() снова явно не используется.

Path.cwd() из pathlib модуля возвращает путь к текущей директории как объект c разными полезными и удобными методами такими как .glob('**/*.py').

Директория со скриптом

Текущая рабочая директория может отличаться от директории с текущим Питон-скриптом. Часто, но не всегда можно os.path.dirname(os.path.abspath(__file__)) использовать, чтобы получить директорию с текущим Питон скриптом, но это не всегда работает. Посмотрите на get_script_dir() функцию, которая поддерживает более общий случай.

Если хочется получить данные из файла, расположенного относительно установленного Питон-модуля, то используйте pkgutil.get_data() или setuptools’ pkg_resources.resource_string() вместо построения путей c помощью __file__. Это работает даже, если ваш пакет упакован в архив. В Python 3.7 появился importlib.resources модуль. К примеру, если у вас есть Питон пакет data внутри которого лежит файл.txt, то чтобы достать текст:

import importlib.resources

text = importlib.resources.read_text('data', 'файл.txt') 

Если вы хотите найти место куда пользовательские данные можно положить, то appdirs модуль предоставляет переносимый способ:

import appdirs   # $ pip install appdirs

user_data_dir = appdirs.user_data_dir("Название приложения", "Кто создал")

Разные платформы (Windows, MacOS, Linux) используют разные соглашения, appdirs позволяет не плодить сущностей и использовать на каждой платформе подходящие директории.

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

Эта статья предназначена как раз для начинающих разработчиков. В ней описаны 8 крайне важных команд для работы с файлами, папками и файловой системой в целом. Все примеры из этой статьи размещены в Google Colab Notebook (ссылка на ресурс — в конце статьи).

Показать текущий каталог


Самая простая и вместе с тем одна из самых важных команд для Python-разработчика. Она нужна потому, что чаще всего разработчики имеют дело с относительными путями. Но в некоторых случаях важно знать, где мы находимся.

Относительный путь хорош тем, что работает для всех пользователей, с любыми системами, количеством дисков и так далее.

Так вот, для того чтобы показать текущий каталог, нужна встроенная в Python OS-библиотека:

import os
os.getcwd()

Ее легко запомнить, так что лучше выучить один раз, чем постоянно гуглить. Это здорово экономит время.

Имейте в виду, что я использую Google Colab, так что путь /content является абсолютным.

Проверяем, существует файл или каталог


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

Функция os.path.exists () принимает аргумент строкового типа, который может быть либо именем каталога, либо файлом.

В случае с Google Colab при каждом запуске создается папка sample_data. Давайте проверим, существует ли такой каталог. Для этого подойдет следующий код:

os.path.exists('sample_data')

Эта же команда подходит и для работы с файлами:

os.path.exists(‘sample_data/README.md’)

Если папки или файла нет, команда возвращает false.

Объединение компонентов пути


В предыдущем примере я намеренно использовал слеш «/» для разделителя компонентов пути. В принципе это нормально, но не рекомендуется. Если вы хотите, чтобы ваше приложение было кроссплатформенным, такой вариант не подходит. Так, некоторые старые версии ОС Windows распознают только слеш «» в качестве разделителя.

Но не переживайте, Python прекрасно решает эту проблему благодаря функции os.path.join (). Давайте перепишем вариант из примера в предыдущем пункте, используя эту функцию:

os.path.exists(os.path.join('sample_data', 'README.md'))


Создание директории


Ну а теперь самое время создать директорию с именем test_dir внутри рабочей директории. Для этого можно использовать функцию
os.mkdir():

os.mkdir('test_dir')

Давайте посмотрим, как это работает на практике.

Если же мы попытаемся создать каталог, который уже существует, то получим исключение.

Именно поэтому рекомендуется всегда проверять наличие каталога с определенным названием перед созданием нового:

if not os.path.exists('test_dir'):
    os.mkdir('test_dir')

Еще один совет по созданию каталогов. Иногда нам нужно создать подкаталоги с уровнем вложенности 2 или более. Если мы все еще используем os.mkdir (), нам нужно будет сделать это несколько раз. В этом случае мы можем использовать os.makedirs (). Эта функция создаст все промежуточные каталоги так же, как флаг mkdir -p в системе Linux:

os.makedirs(os.path.join('test_dir', 'level_1', 'level_2', 'level_3'))

Вот что получается в результате.

Показываем содержимое директории


Еще одна полезная команда — os.listdir(). Она показывает все содержимое каталога.

Команда отличается от os.walk (), где последний рекурсивно показывает все, что находится «под» каталогом. os.listdir () намного проще в использовании, потому что просто возвращает список содержимого:

os.listdir('sample_data')

В некоторых случаях нужно что-то более продвинутое — например, поиск всех CSV-файлов в каталоге «sample_data». В этом случае самый простой способ — использовать встроенную библиотеку glob:

from glob import globlist(glob(os.path.join('sample_data', '*.csv')))

Перемещение файлов


Самое время попробовать переместить файлы из одной папки в другую. Рекомендованный способ — еще одна встроенная библиотека shutil.
Сейчас попробуем переместить все CSV-файлы из директории «sample_data» в директорию «test_dir». Ниже — пример кода для выполнения этой операции:

import shutilfor file in list(glob(os.path.join('sample_data', '*.csv'))):
    shutil.move(file, 'test_dir')

Кстати, есть два способа выполнить задуманное. Например, мы можем использовать библиотеку OS, если не хочется импортировать дополнительные библиотеки. Как os.rename, так и os.replace подходят для решения задачи.

Но обе они недостаточно «умные», чтобы позволить перемесить файлы в каталог.

Чтобы все это работало, нужно явно указать имя файла в месте назначения. Ниже — код, который это позволяет сделать:

for file in list(glob(os.path.join('test_dir', '*.csv'))):
    os.rename(
        file,
        os.path.join(
            'sample_data',
            os.path.basename(file)
    ))

Здесь функция os.path.basename () предназначена для извлечения имени файла из пути с любым количеством компонентов.

Другая функция, os.replace (), делает то же самое. Но разница в том, что os.replace () не зависит от платформы, тогда как os.rename () будет работать только в системе Unix / Linux.

Еще один минус — в том, что обе функции не поддерживают перемещение файлов из разных файловых систем, в отличие от shutil.

Поэтому я рекомендую использовать shutil.move () для перемещения файлов.

Копирование файлов


Аналогичным образом shutil подходит и для копирования файлов по уже упомянутым причинам.

Если нужно скопировать файл README.md из папки «sample_data» в папку «test_dir», поможет функция shutil.copy():

shutil.copy(
    os.path.join('sample_data', 'README.md'),
    os.path.join('test_dir')
)

Удаление файлов и папок


Теперь пришел черед разобраться с процедурой удаления файлов и папок. Нам здесь снова поможет библиотека OS.

Когда нужно удалить файл, нужно воспользоваться командой os.remove():

os.remove(os.path.join('test_dir', 'README(1).md'))

Если требуется удалить каталог, на помощь приходит os.rmdir():

os.rmdir(os.path.join('test_dir', 'level_1', 'level_2', 'level_3'))

Однако он может удалить только пустой каталог. На приведенном выше скриншоте видим, что удалить можно лишь каталог level_3. Что если мы хотим рекурсивно удалить каталог level_1? В этом случае зовем на помощь shutil.

Функция shutil.rmtree() сделает все, что нужно:

shutil.rmtree(os.path.join('test_dir', 'level_1'))

Пользоваться ею нужно с осторожностью, поскольку она безвозвратно удаляет все содержимое каталога.

Собственно, на этом все. 8 важных операций по работе с файлами и каталогами в среде Python мы знаем. Что касается ссылки, о которой говорилось в анонсе, то вот она — это Google Colab Network с содержимым, готовым к запуску.

16.10.2020
Python

При работе с файлами в каталогах в Python всегда рекомендуется использовать абсолютные пути. Однако, если вы работаете с относительными путями, вам необходимо понимать концепцию текущего рабочего каталога и то, как найти или изменить текущий рабочий каталог. Абсолютный путь указывает расположение файла или каталога, начиная с корневого каталога, а относительный путь начинается с текущего рабочего каталога.

Когда вы запускаете сценарий Python, в качестве текущего рабочего каталога устанавливается каталог, из которого выполняется сценарий.

Модуль os python обеспечивает переносимый способ взаимодействия с операционной системой. Модуль является частью стандартной библиотеки Python и включает методы поиска и изменения текущего рабочего каталога.

Получение текущего рабочего каталога в Python

Метод getcwd() модуля os в Python возвращает строку, содержащую абсолютный путь к текущему рабочему каталогу. Возвращенная строка не включает завершающий символ косой черты.

Чтобы использовать методы модуля os, вы должны импортировать модуль в верхней части файла.

Ниже приведен пример, показывающий, как распечатать текущий рабочий каталог:

# Import the os module
import os

# Get the current working directory
cwd = os.getcwd()

# Print the current working directory
print("Current working directory: {0}".format(cwd))

# Print the type of the returned object
print("os.getcwd() returns an object of type: {0}".format(type(cwd)))

Результат будет выглядеть примерно так:

Current working directory: /home/linuxize/Desktop
os.getcwd() returns an object of type: <class 'str'>

Если вы хотите найти каталог, в котором находится скрипт, используйте os.path.realpath(__file__) . Он вернет строку, содержащую абсолютный путь к запущенному скрипту.

Изменение текущего рабочего каталога в Python

Чтобы изменить текущий рабочий каталог в Python, используйте метод chdir() .

Метод принимает один аргумент — путь к каталогу, в который вы хотите перейти. Аргумент path может быть абсолютным или относительным.

Вот пример:

# Import the os module
import os

# Print the current working directory
print("Current working directory: {0}".format(os.getcwd()))

# Change the current working directory
os.chdir('/tmp')

# Print the current working directory
print("Current working directory: {0}".format(os.getcwd()))

Результат будет выглядеть примерно так:

Current working directory: /home/linuxize/Desktop
Current working directory: /tmp

Аргумент, передаваемый методу chdir() должен быть каталогом, в противном случае NotADirectoryError исключение NotADirectoryError . Если указанный каталог не существует, возникает исключение FileNotFoundError . Если у пользователя, от имени которого выполняется сценарий, нет необходимых разрешений, возникает исключение PermissionError .

# Import the os module
import os

path = '/var/www'

try:
    os.chdir(path)
    print("Current working directory: {0}".format(os.getcwd()))
except FileNotFoundError:
    print("Directory: {0} does not exist".format(path))
except NotADirectoryError:
    print("{0} is not a directory".format(path))
except PermissionError:
    print("You do not have permissions to change to {0}".format(path))

Выводы

Чтобы найти текущий рабочий каталог в Python, используйте os.getcwd() , а для изменения текущего рабочего каталога используйте os.chdir(path) .

Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.

Обработка файлов в Python с помощью модуля os включает создание, переименование, перемещение, удаление файлов и папок, а также получение списка всех файлов и каталогов и многое другое.

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

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

Модуль встроенный, поэтому для работы с ним не нужно ничего устанавливать.

Вывод текущей директории

Для получения текущего рабочего каталога используется os.getcwd():

import os

# вывести текущую директорию
print("Текущая деректория:", os.getcwd())

os.getcwd() возвращает строку в Юникоде, представляющую текущий рабочий каталог. Вот пример вывода:

Текущая деректория: C:python3bin

Создание папки

Для создания папки/каталога в любой операционной системе нужна следующая команда:

# создать пустой каталог (папку)
os.mkdir("folder")

После ее выполнения в текущем рабочем каталоге тут же появится новая папка с названием «folder».

Если запустить ее еще раз, будет вызвана ошибка FileExistsError, потому что такая папка уже есть. Для решения проблемы нужно запускать команду только в том случае, если каталога с таким же именем нет. Этого можно добиться следующим образом:

# повторный запуск mkdir с тем же именем вызывает FileExistsError, 
# вместо этого запустите:
if not os.path.isdir("folder"):
     os.mkdir("folder")

Функция os.path.isdir() вернет True, если переданное имя ссылается на существующий каталог.

Изменение директории

Менять директории довольно просто. Проделаем это с только что созданным:

# изменение текущего каталога на 'folder'
os.chdir("folder")

Еще раз выведем рабочий каталог:

# вывод текущей папки
print("Текущая директория изменилась на folder:", os.getcwd())

Вывод:

Текущая директория изменилась на folder: C:python3binfolder

Создание вложенных папок

Предположим, вы хотите создать не только одну папку, но и несколько вложенных:

# вернуться в предыдущую директорию
os.chdir("..")

# сделать несколько вложенных папок
os.makedirs("nested1/nested2/nested3")

Это создаст три папки рекурсивно, как показано на следующем изображении:

Создание вложенных папок

Создание файлов

Для создания файлов в Python модули не нужны. Можно использовать встроенную функцию open(). Она принимает название файла, который необходимо создать в качестве первого параметра и желаемый режим открытия — как второй:

# создать новый текстовый файл
text_file = open("text.txt", "w")
# запить текста в этот файл
text_file.write("Это текстовый файл")

w значит write (запись), a — это appending (добавление данных к уже существующему файлу), а r — reading (чтение). Больше о режимах открытия можно почитать здесь.

Переименование файлов

С помощью модуля os достаточно просто переименовать файл. Поменяем название созданного в прошлом шаге.

# переименовать text.txt на renamed-text.txt
os.rename("text.txt", "renamed-text.txt")

Функция os.rename() принимает 2 аргумента: имя файла или папки, которые нужно переименовать и новое имя.

Перемещение файлов

Функцию os.replace() можно использовать для перемещения файлов или каталогов:

# заменить (переместить) этот файл в другой каталог
os.replace("renamed-text.txt", "folder/renamed-text.txt")

Стоит обратить внимание, что это перезапишет путь, поэтому если в папке folder уже есть файл с таким же именем (renamed-text.txt), он будет перезаписан.

Список файлов и директорий

# распечатать все файлы и папки в текущем каталоге
print("Все папки и файлы:", os.listdir())

Функция os.listdir() возвращает список, который содержит имена файлов в папке. Если в качестве аргумента не указывать ничего, вернется список файлов и папок текущего рабочего каталога:

Все папки и файлы: ['folder', 'handling-files', 'nested1', 'text.txt']

А что если нужно узнать состав и этих папок тоже? Для этого нужно использовать функцию os.walk():

# распечатать все файлы и папки рекурсивно
for dirpath, dirnames, filenames in os.walk("."):
    # перебрать каталоги
    for dirname in dirnames:
        print("Каталог:", os.path.join(dirpath, dirname))
    # перебрать файлы
    for filename in filenames:
        print("Файл:", os.path.join(dirpath, filename))

os.walk() — это генератор дерева каталогов. Он будет перебирать все переданные составляющие. Здесь в качестве аргумента передано значение «.», которое обозначает верхушку дерева:

Каталог: .folder
Каталог: .handling-files
Каталог: .nested1
Файл: .text.txt
Файл: .handling-fileslisting_files.py
Файл: .handling-filesREADME.md
Каталог: .nested1nested2
Каталог: .nested1nested2nested3

Метод os.path.join() был использован для объединения текущего пути с именем файла/папки.

Удаление файлов

Удалим созданный файл:

# удалить этот файл
os.remove("folder/renamed-text.txt")

os.remove() удалит файл с указанным именем (не каталог).

Удаление директорий

С помощью функции os.rmdir() можно удалить указанную папку:

# удалить папку
os.rmdir("folder")

Для удаления каталогов рекурсивно необходимо использовать os.removedirs():

# удалить вложенные папки
os.removedirs("nested1/nested2/nested3")

Это удалит только пустые каталоги.

Получение информации о файлах

Для получения информации о файле в ОС используется функция os.stat(), которая выполняет системный вызов stat() по выбранному пути:

open("text.txt", "w").write("Это текстовый файл")

# вывести некоторые данные о файле
print(os.stat("text.txt"))

Вывод:

os.stat_result(st_mode=33206, st_ino=14355223812608232, st_dev=1558443184, st_nlink=1, st_uid=0, st_gid=0, st_size=19, st_atime=1575967618, st_mtime=1575967618, st_ctime=1575966941)

Это вернет кортеж с отдельными метриками. В их числе есть следующие:

    • st_size — размер файла в байтах
    • st_atime — время последнего доступа в секундах (временная метка)
    • st_mtime — время последнего изменения
    • st_ctime — в Windows это время создания файла, а в Linux — последнего изменения метаданных

Для получения конкретного атрибута нужно писать следующим образом:

# например, получить размер файла
print("Размер файла:", os.stat("text.txt").st_size)

Вывод:

Размер файла: 19

На этой странице больше об атрибутах.

Выводы

Работать с файлами и каталогами в Python очень просто. Не имеет значения даже используемая операционная система, хотя отдельные уникальные для системы функции можно использовать: например, os.chown() или os.chmod() в Linux. Более подробно эта тема освещена в официальной документации Python.

Понравилась статья? Поделить с друзьями:
  • Как составить свое резюме если нет опыта работы
  • Как составить акт применение применения
  • Как найти значение выражения а 7843
  • Как составить статью для девочек
  • Как найти общую стоимость продукции