Пути к файлам в Python (os.path)

Для начинающих изучать алготрейдинг на Python с нуля при изучении самых простых программных кодов зачастую непонятна система формирования путей. Понятный вариант, как например “C:\My_prog\Data\fail.txt”, заменяется сложным кодом. Давайте разберемся в этом вопросе.

Имя файла

Модуль sys в Python предоставляет функционал для работы с системными параметрами и функциями интерпретатора. Нас интересует функция sys.argv — это встроенная команда, в которой перечислены все параметры командной строки, передаваемых скрипту на Python.

sys.argv – возвращает список (массив), содержащий аргументы командной строки:

  • Первым элементом sys.argv[0] является имя самого запущенного скрипта
  • Все последующие элементы sys.argv – это аргументы, переданные скрипту в командной строке через пробел

Создадим программу my_script.py

import sys  # импортируем модуль

print(sys.argv)
print(type(sys.argv))
print(sys.argv[0])

Давайте запустим нашу программу my_script.py с помощью команды:

python my_script.py arg1 arg2 arg3 (для примера передаем некие три аргумента)

Получаем:

['my_script.py', 'arg1', 'arg2', 'arg3'] 
<class 'list'> 
my_script.py

Видно, что в первом элемента sys.argv[0] списка содержится только имя запущенного файла, без элементов списка с аргументами. И для наших целей мы будем использовать не просто sys.argv, а именно sys.argv[0].

Абсолютный путь к файлу

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

Нас интересуете функция os.path.abspath(), которая преобразует относительный путь в абсолютный.

Абсолютный путь – это путь от корневого каталога файловой системы. То есть он описывает полное расположение файла или директории.

Например:

в операционной системе Linux – /home/user/docs/my_script.py

в операционной системе Windows – C:\Users\Sergey\Documents\my_script.py 

Относительные пути задают расположение относительно текущего каталога

Например: docs/files/my_script.py 

Чтобы преобразовать относительный путь в абсолютный, используется функция os.path.abspath, которая дописывает относительный путь в абсолютный относительно текущей директории, в которой запущен скрипт.

Это бывает полезно для однозначного определения расположения и последующей работы с файлами по абсолютному пути.

import os.path
import sys  


print(sys.argv[0])
print(os.path.abspath(sys.argv[0]))

получаем

c:/My_prog/algopack/my_script.py
c:\My_prog\algopack\my_script.py

 

Имя директории из пути к файлу

Функция os.path.dirname() модуля os.path возвращает имя каталога в пути к директории, в которой находится текущий файл.

import os.path
import sys  


print(sys.argv[0])
print(os.path.abspath(sys.argv[0]))
print(os.path.dirname(os.path.abspath(sys.argv[0])))

после запуска программы получаем

c:/_Code_home/algopack/my_script.py
c:\_Code_home\algopack\my_script.py
c:\_Code_home\algopack

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

Создаем путь до нужного нам файла или каталога

Функция os.path.join() используется для объединения одного или нескольких путей к файлам и каталогам.

Функция os.path.join обладает возможностями:

  • Принимает один или более аргументов с путями
  • Соединяет части пути используя разделитель в соответствии с текущей ОС (слеш или обратный слеш)
  • Удаляет ненужные слеши в конце и начале путей при объединении или добавляет нужные слеши.

Функция упрощает конкатенацию (склеивание) путей и избавляет от необходимости вручную следить за разделителями и слешами.

выполнение print(os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])))) выведет путь c:\My_prog\algopack

 

Вот и настал момент истины – теперь мы можем определить путь к любому файлу или каталогу!

Например у нас стоит задача – открыть текстовый файл “111.txt”, который лежит в одной папке с исполняемым скриптом. Код скрипта будет следующий:

import os.path
import sys

script_dir = os.path.dirname(os.path.abspath(sys.argv[0])) # папка со скриптом
text_file = os.path.join(script_dir, '111.txt') # объединяем путь к каталогу с названием файла, собираем абсолютный путь к файлу 111.txt
with open(text_file, 'r', encoding='utf-8') as file: # Открываем файл
    text = file.read() # Читаем содержимое в переменную text
    print(text) # выводим содержимое файла

можно сократить код:

import os.path
import sys 

with open(os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])),'111.txt'), 'r', encoding='utf-8') as file:
    text = file.read()
    print(text)

Однако первый вариант все же понятен в восприятии.

А можно ли было не вникать во все вышеизложенное и открыть файл следующим образом?

with open('111.txt', 'r', encoding='utf-8') as file:
    text = file.read()
    print(text)

Конечно можно. Но надо учитывать, что использование модуля os.path для формирования относительных путей вместо жёстко заданных абсолютных путей имеет несколько преимуществ:

  1. Переносимость. Скрипт с относительными путями можно запустить из любого места файловой системы, он найдёт нужные ему файлы относительно своего расположения.
  2. Удобство дебага и тестирования. Не нужно менять пути при запуске скрипта на другой машине или из другой директории.
  3. Упрощение деплоя. При развёртывании скрипта на сервере, не нужно менять жёстко заданные пути. Достаточно скопировать файлы скрипта и ресурсов.
  4. Кроссплатформенность. Конструирование путей через os.path учитывает разделители в Windows и Linux.

Таким образом гибкость конструирования относительных путей в итоге экономит время и упрощает поддержку кода.

 

И в заключении давайте представим, что текстовый файл 111.txt, находится в папке Data рядом со скриптом. В этом случае

text_file = os.path.join(script_dir, 'Data','111.txt')

И если папка Data расположена на один уровень выше относительно скрипта, то можно еще раз скорректировать путь с помощью добавления ../  :
text_file = os.path.join(script_dir, '../Data/','111.txt')

 

На этом этом этапе информации по путям в программах Python для начинающего алготрейдера будет достаточно.

Оцените статью
Репост в TG и VK
Алготрейдинг шаг за шагом. Создай торгового робота на Python с нуля по нашим урокам. Автоматизируй торговлю на бирже по собственной стратегии.