Путь к файлу не включает

Обновлено: 04.07.2024

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

В PyCharm есть несколько предопределенных переменных:

$USER_HOME$: обозначает ваш домашний каталог.

$PROJECT_DIR$: обозначает каталог, в котором хранится ваш проект.

Создать новую переменную пути

Например, у вас есть скрипт Python, который обрабатывает некоторые данные, хранящиеся в вашей системе в файле report.csv. Вы создаете конфигурацию запуска/отладки для запуска этого скрипта и хотите поделиться этой конфигурацией со своими товарищами по команде через VCS.

Нажмите Ctrl+Alt+S, чтобы открыть настройки IDE, и выберите Внешний вид и поведение | Переменные пути .

Нажмите и введите имя новой переменной (например, DATA_PATH ) и ее значение, указывающее на целевой каталог с файлом данных на вашем диске.

Поделитесь конфигурацией запуска/отладки через вашу систему контроля версий.

Файл .idea/runConfiguration/.xml:

Запустить/отладить файл конфигурации с добавленной переменной пути

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

Игнорируемые переменные пути

Когда вы открываете проект, PyCharm проверяет наличие неразрешенных переменных пути. Если IDE обнаружит их, она попросит вас определить для них значения. Если вы не хотите этого делать (например, если вы не собираетесь использовать файлы или каталоги с неразрешенными переменными пути), вы можете добавить их в список игнорируемых переменных.

Вы также можете использовать список игнорируемых переменных, если, например, аргумент программы, переданный JVM в конфигурации запуска/отладки, имеет тот же формат, что и внутренняя переменная пути ($SOME_STRING$). В этом случае вы можете добавить этот параметр в список игнорируемых переменных, чтобы избежать путаницы. Введите SOME_STRING в поле «Игнорируемые переменные» в диалоговом окне «Переменные пути».

Я пишу программу для работы с базой данных, и моим объектом тестирования является Personica (обычно я использую переменную вместо пути к файлу, но для тестирования и демонстрационных целей у меня есть просто строка). В этом же месте на моем компьютере есть текстовый файл (кстати, я изменил свое имя пользователя здесь, потому что я параноик), но он говорит:

Это строка кода:

Я уверен, что он там есть, и когда я копирую этот адрес в проводник Windows, он перенаправляет меня прямо к текстовому файлу.

Кто-нибудь знает, почему это не работает?

OTOH, так как ваш текстовый файл находится в том же каталоге, что и ваш скрипт, open('personica.txt') сделает свое дело.

Вы уверены, что в имени файла или документации проекта нет символов, отличных от английского? Что произойдет, если вы попытаетесь открыть совершенно другой файл в другом месте? Что, если вы переименуете файл, который у вас уже есть? Что, если вы переместите его в другой каталог (например, на один уровень выше)?

2 ответа 2

Новый модуль pathlib (доступный в Python >= 3.4) отлично подходит для работы с объектами, подобными пути (как для Windows, так и для других ОС).

It’s Paths — Пути вниз

Для упрощения: вы можете построить любой путь (объекты пути к каталогу и файлу обрабатываются одинаково) как объект, который может быть объектом абсолютного пути или объектом относительного пути. . Вы можете использовать необработанные строки для создания сложных путей (например, r'string' ), и pathlib будет очень прощающим. Однако обратите внимание, что есть лучшие способы создания путей, чем необработанные строки (см. ниже).

Вот примеры:

Обратите внимание: если вы используете Windows, pathlib прощает вам использование «неправильной косой черты» во втором примере. См. обсуждение в конце о том, почему вы, вероятно, должны всегда использовать косую черту.

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

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

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

Но вы также можете просто взять текст напрямую!

<р>. и ПИШИТЕ текст напрямую!

Проверьте, является ли это файлом или каталогом (и существует ли он) следующим образом:

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

Чтобы сделать файл только если он не существует, используйте exists_ok=False :

Создайте новый каталог (в текущем каталоге, Path() ) следующим образом:

Получить расширение файла или имя файла пути следующим образом:

Используйте имя для всей последней части пути (основа и расширение, если они есть):

Переименуйте файл с помощью метода with_name (который возвращает тот же объект пути, но с новым именем файла):

Вы можете перебирать все "вещи" в каталоге, используя iterdir :

Боковая панель: обратная косая черта ( \ )

Будьте осторожны при использовании обратной косой черты в строке пути, особенно при заканчивании пути обратной косой чертой. Как и в случае с любой строкой, Python будет читать этот обратный слэш в конце как escape-символ даже в режиме необработанного ввода. Обратите внимание:

Таким образом, это даст довольно загадочное сообщение об ошибке, если вы не знаете об этой проблеме:

Причина этой ошибки в том, что \' считается одиночной кавычкой в строке. Это прекрасно работает: '\'' (вторая одинарная кавычка завершает строку).

Если вы настаиваете на использовании обратной косой черты, обязательно используйте режим необработанного ввода, иначе вы столкнетесь с проблемами. Например, символ «\t» представляет вкладку. Итак, когда вы делаете это (без необработанного ввода):

Вы помещаете символ табуляции в свой путь. Это совершенно законно, и Python не будет жаловаться, пока вы не сделаете что-то, что заставит Windows попытаться превратить его в настоящий путь Windows:

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

Предотвращение вашей проблемы

Ваша проблема возникла, когда вы создали файл и по ошибке добавили двойное расширение. Чтобы предотвратить эту проблему с помощью pathlib , используйте метод touch для создания файла:

В Windows полный путь к каталогу начинается с буквы диска (C:, D: и т. д.). В Linux и OS-X он начинается с «/», что называется root. Каталоги разделяются косой чертой «/». Вы можете найти полный путь к каталогу и имя файла через его «Свойства». Посмотрите, как это делается, в этом FAQ.

Ссылка на файл в Windows

  • Python позволяет использовать косую черту "/" в стиле OS-X/Linux даже в Windows. Поэтому вы можете ссылаться на файл как 'C:/Users/narae/Desktop/alice.txt'. РЕКОМЕНДУЕТСЯ.
  • Если вы используете обратную косую черту, так как это специальный символ в Python, вы должны помнить об экранировании каждого экземпляра: 'C:\\Users\\narae\\Desktop\\alice.txt'< /li>
  • Кроме того, вы можете поставить перед всей строкой имени файла маркер необработанной строки "r": r'C:\Users\narae\Desktop\alice.txt'. Таким образом, все в строке интерпретируется как буквальный символ, и вам не нужно экранировать каждую обратную косую черту.

Сочетания имен файлов и CWD (текущий рабочий каталог)

Таким образом, использование полного пути к каталогу и имени файла всегда работает; вы должны использовать этот метод. Однако вы могли видеть файлы, называемые только по имени, например, 'alice.txt' в Python. Как это делается?

Концепция текущего рабочего каталога (CWD) здесь имеет решающее значение. Вы можете думать об этом как о папке, в которой в данный момент работает ваш Python. До сих пор мы использовали абсолютный путь, который начинается с самого верхнего каталога. Но если ваша ссылка на файл не начинается сверху (например, 'alice.txt', 'ling1330/alice.txt'), Python предполагает, что она начинается в CWD ("относительный путь").

    В сценарии Python:
    Когда вы выполняете свой сценарий, ваш CWD устанавливается в каталог, где находится ваш сценарий. Таким образом, вы можете обращаться к файлу в скрипте по его имени только при условии, что файл и скрипт находятся в одном каталоге. Пример:

  1. Измените CWD на каталог файла или
  2. Скопируйте или переместите файл на CWD. (Не рекомендуется, так как CWD вашей оболочки может измениться.)

Поиск и изменение CWD

Проблема: список папок и дисков

Недавно во время работы над проектом коллега спросил, можно ли составить список содержимого дисков в Python. Конечно вы можете. Более того, поскольку это совсем несложно, я хотел бы использовать этот пример, чтобы проиллюстрировать ключевые рекомендации, рекомендуемые для работы с путями на дисках.

Шаг 1. Как ввести правильный путь?

Предполагая, что вы хотите точно получить список определенного пути, мы начнем с выбора пользовательского каталога в системе Windows 10, что в основном является воспроизводимым примером:

Переменные, назначенные при выполнении, немедленно вызывают ошибку:

Интерпретатор не понимает последовательность символов \U, так как она инициирует символы Unicode аналогичной последовательности. Эта проблема возникает из-за того, что в системе Windows в качестве разделителя пути используется обратная косая черта «\», а в Linux используется косая черта «/».К сожалению, поскольку разделитель Windows также является инициатором различных специальных символов или экранирования в Unicode, он явно все путает. Точно так же, как мы не ожидаем в ближайшее время какой-либо согласованности в использовании десятичных разделителей в разных странах, наш единственный выбор — выбрать одно из трех решений.

Решение 1 — отвратительный вариант

Просто избегайте разделителя Windows и вместо этого пишите путь, используя только разделители Linux:

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

Решение 2 — еще более отвратительный вариант

Используйте escape-последовательности.

Что меня беспокоит помимо неразборчивости, так это то, что escape-последовательности не используются при каждой комбинации символов-разделителей, только перед «U» и «b».

Решение 3 — элегантное

Используйте необработанные строки с префиксом "r", чтобы указать, что специальные символы не должны оцениваться.

Шаг 2. Сканирование файлов

Вернемся к нашей задаче перечислить все элементы в папке. Мы уже знаем путь.

Простая команда os.listdir выводит список всех строк, т. е. только пути к файлам. Здесь и во всех других примерах я использую подсказки типов для дополнительной документации кода. Этот синтаксис стал доступен, начиная с версии Python 3.5.

С файлом все в порядке, но меня больше интересует статистика файла, для которой у нас есть os.stat.

Шаг 3. Объединение путей

Чтобы передать путь к файлу, мы должны сначала объединить имя файла и путь. Я часто видел следующие конструкции в дикой природе и даже использовал их, когда начинал. Например:

A и B отвратительны, потому что они соединяют строки знаком "+", что не нужно в Python.

B особенно отвратительна, потому что в Windows нужен двойной разделитель, иначе он будет расценен как escape-последовательность для закрывающей кавычки.

C и D несколько лучше, так как они используют форматирование строк, но они по-прежнему не решают проблему системной зависимости. Если я применяю результат под Windows, я получаю функциональный, но несогласованный путь со смесью разделителей.

Решение, не зависящее от ОС

Решением от Python является os.sep или os.path.sep. Оба возвращают разделитель путей соответствующей системы. Они функционально идентичны, но второй, более явный синтаксис сразу показывает используемый разделитель.

Это означает, что можно написать:

Результат будет лучше, но за счет усложнения кода, если вы объедините несколько сегментов пути.

Поэтому принято объединять элементы пути с помощью связывания строк. Это еще короче и универсальнее:

Первый полный запуск

Перейдем в каталог:

Один из результатов (не показан) — это st_atime, время последнего обращения к нему, st_mtime для последней модификации и st_ctime для времени создания. Кроме того, st_size дает размер файла в байтах. На данный момент все, что я хочу знать, это размер и дату последнего изменения, поэтому я решил сохранить простой формат списка.

Последняя функция с рекурсией

Результат сначала кажется удовлетворительным, но возникают две новые проблемы. Listdir не делает различий между файлами и папками, обращается только к уровню папок и не обрабатывает вложенные папки. Следовательно, нам нужна рекурсивная функция, которая различает файлы и папки. os.path.isdir проверяет для нас, есть ли папка ниже пути.

Как сделать результаты полезными в качестве фрейма данных

Готово! Мы решили проблему менее чем в 10 строках. Поскольку я планировал иметь filesurvey в виде списка кортежей, я могу легко перенести результат во фрейм данных panda и проанализировать его там, чтобы вычислить итоговые значения, сохраненные в папках и т. д.

. но, к сожалению, это не самая лучшая практика

Я знаю, в блоге обещали решить проблему с помощью лучших практик.

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

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

Читайте также: