- Вопрос или проблема
- Понимание абсолютных и относительных путей
- Понимание “текущего рабочего каталога”
- Проверка фактического имени файла и пути
- Убедитесь, что все папки в пути к файлу существуют.
- Pycharm имеет встроенные настройки “Активного Каталога”
- Ответ или решение
- Ошибка FileNotFoundError / IOError: ‘[Errno 2] No such file or directory’ при использовании функции open() в Python
- Основы поиска файлов в Python
- Решения проблемы
- Дополнительно о путях
- Заключение
Вопрос или проблема
Я пытаюсь открыть файл recentlyUpdated.yaml
из моего Python-скрипта. Но когда я пытаюсь использовать:
open('recentlyUpdated.yaml')
Я получаю ошибку, которая говорит:
IOError: [Errno 2] No such file or directory: 'recentlyUpdated.yaml'
Почему? Как я могу исправить проблему?
Позвольте мне объяснить, как Python находит файлы:
- Абсолютный путь — это путь, который начинается с корневого каталога вашего компьютера, например
C:\Python\scripts
, если вы на Windows. - Относительный путь — это путь, который не начинается с корневого каталога вашего компьютера, а является относительным к чему-то, что называется рабочим каталогом.
Если вы попытаетесь сделать open('recentlyUpdated.yaml')
, Python увидит, что вы передаете относительный путь, поэтому он будет искать файл внутри текущего рабочего каталога.
Чтобы диагностировать проблему:
- Убедитесь, что файл существует (и имеет правильное расширение): используйте
os.listdir()
, чтобы увидеть список файлов в текущем рабочем каталоге. - Убедитесь, что вы находитесь в ожидаемом каталоге, используя
os.getcwd()
.
(Если вы запускаете свой код из IDE, вы можете находиться в другом каталоге.)
os.chdir(dir)
, где dir
— это каталог, содержащий файл. Это изменит текущий рабочий каталог. Затем откройте файл, используя только его имя, например open("file.txt")
.open
.Кстати:
- Используйте сырой строковый литерал (
r""
), если ваш путь использует обратные слэши, например так:dir = r'C:\Python32'
- Если вы не используете сырой строковый литерал, вам нужно экранировать каждый обратный слэш:
'C:\\User\\Bob\\...'
- Прямые слэши также работают на Windows
'C:/Python32'
и не требуют экранирования.
- Если вы не используете сырой строковый литерал, вам нужно экранировать каждый обратный слэш:
Пример: Предположим, что file.txt
находится в C:\Folder
.
Чтобы открыть его, вы можете сделать:
os.chdir(r'C:\Folder')
open('file.txt') # относительный путь, ищет внутри текущего рабочего каталога
или
open(r'C:\Folder\file.txt') # абсолютный путь
Скорее всего, проблема заключается в том, что вы используете относительный путь к файлу для открытия файла, но текущий рабочий каталог не установлен на то, на что вы думаете.
Это распространенное заблуждение, что относительные пути относительны к местоположению python-скрипта, но это неправда. Относительные пути к файлам всегда относятся к текущему рабочему каталогу, и текущий рабочий каталог не обязательно является местом вашего python-скрипта.
У вас есть три варианта:
-
Используйте абсолютный путь для открытия файла:
file = open(r'C:\path\to\your\file.yaml')
-
Сгенерируйте путь к файлу относительно вашего python-скрипта:
from pathlib import Path script_location = Path(__file__).absolute().parent file_location = script_location / 'file.yaml' file = file_location.open()
(Смотрите также: Как получить путь и имя файла, который в настоящее время выполняется?)
-
Измените текущий рабочий каталог перед открытием файла:
import os os.chdir(r'C:\path\to\your\file') file = open('file.yaml')
Другие распространенные ошибки, которые могут вызвать ошибку “файл не найден”, включают:
-
Случайное использование управляющих последовательностей в пути к файлу:
path="C:\Users\newton\file.yaml" # Неправильно! '\n' в 'Users\newton' является символом новой строки!
Чтобы избежать этой ошибки, не забудьте использовать сырьевые строковые литералы для путей к файлам:
path = r'C:\Users\newton\file.yaml' # Правильно!
(Смотрите также: Путь Windows в Python)
-
Забывание о том, что Windows не отображает расширения файлов:
Поскольку Windows не отображает известные расширения файлов, иногда, когда вы думаете, что ваш файл называется
file.yaml
, на самом деле он называетсяfile.yaml.yaml
. Дважды проверьте расширение вашего файла.
Файл может существовать, но иметь другой путь. Попробуйте указать абсолютный путь к файлу.
Попробуйте функцию os.listdir()
, чтобы проверить, что хотя бы Python видит файл.
Попробуйте так:
file1 = open(r'Drive:\Dir\recentlyUpdated.yaml')
Если в VSCode, посмотрите рабочую область. Если вы в другой рабочей области, эта ошибка может возникнуть.
Возможно, вы закрыли ‘file1’.
Просто используйте флаг ‘w’, который создаст новый файл:
file1 = open('recentlyUpdated.yaml', 'w')
mode — это необязательная строка, указывающая режим, в котором файл открыт. По умолчанию он равен ‘r’, что означает открытие для чтения в текстовом режиме. Другие распространенные значения — ‘w’ для записи (усечение файла, если он уже существует)…
(смотрите также https://docs.python.org/3/library/functions.html?highlight=open#open)
Понимание абсолютных и относительных путей
Термин путь означает именно то, что он звучит. Он показывает шаги, которые необходимо сделать, чтобы найти файл, входя и выходя из папок. Каждый шаг на пути — это либо имя папки, либо специальное имя .
(что означает текущую папку), либо специальное имя ..
(что означает вернуться в родительскую папку).
Термины абсолютный и относительный также имеют свое обычное английское значение. Относительный путь показывает, где что-то находится относительно какой-то начальной точки; абсолютный путь — это местоположение, начинающееся с вершины.
Пути, которые начинаются с разделителя пути или буквы диска за которой следует разделитель пути (например, C:/foo
) на Windows, являются абсолютными. (На Windows также существуют UNC-пути, которые обязательно являются абсолютными. Большинство людей никогда не придется беспокоиться об этом.)
Пути, которые непосредственно начинаются с имени файла или папки или буквы диска, за которой сразу следует имя файла или папки (например, C:foo
) на Windows, являются относительными.
Понимание “текущего рабочего каталога”
Относительные пути “относительны к” так называемому текущему рабочему каталогу (в дальнейшем сокращенно CWD). В командной строке Linux и Mac используют общий CWD для всех дисков. (В всей файловой системе есть общий “корень”, и может включать несколько физических устройств хранения.) Windows немного отличается: она запоминает самый последний CWD для каждого диска и имеет отдельную функциональность для переключения между дисками, восстанавливая эти старые значения CWD.
Каждый процесс (это включает терминальные/командные окна) имеет свой собственный CWD. Когда программа запускается из командной строки, она получает CWD, который использовал процесс терминала/команды. Когда программа запускается из GUI (двойным щелчком на скрипте, или перетаскиванием чего-то на скрипт, или перетаскиванием скрипта на исполняемый файл Python) или с помощью IDE, CWD может быть чем угодно, в зависимости от деталей.
Важно, что CWD не обязательно является местом нахождения скрипта.
CWD скрипта можно проверить с помощью os.getcwd
и изменить с помощью os.chdir
. Каждая IDE имеет свои собственные правила, которые контролируют начальный CWD; проверьте документацию для получения дополнительных сведений.
Чтобы установить CWD в папку, содержащую текущий скрипт, определите этот путь, а затем установите его:
os.chdir(os.path.dirname(os.path.abspath(__file__)))
Проверка фактического имени файла и пути
-
Существует множество причин, почему путь к файлу может не совпадать с ожиданиями. Например, иногда люди ожидают, что
C:/foo.txt
на Windows означает “файл с именемfoo.txt
на рабочем столе”. Это неверно. На самом деле, этот файл обычно находится вC:/Users/name/Desktop/foo.txt
(заменяяname
на имя текущего пользователя). Он может находиться и в другом месте, если Windows настроена на его другое местоположение. Чтобы найти путь к рабочему столу переносимым способом, смотрите Как получить расположение рабочего стола?.Также распространено неверное подсчитывание
..
в относительном пути или неуместное повторение имени папки в пути. Обращайте особое внимание при построении пути программно. Наконец, помните, что..
не будет иметь никакого эффекта, пока вы уже находитесь в корневом каталоге (/
на Linux или Mac или корень диска на Windows).Будьте особенно внимательны при построении пути на основе ввода пользователя. Если ввод не очищен, могут произойти плохие вещи (например, позволив пользователю извлечь файл в папку, где он перезапишет что-то важное или куда пользователю не следует разрешать записывать файлы).
-
Еще одна распространенная ловушка — это то, что специальный
~
ярлык для домашнего каталога текущего пользователя не работает в абсолютном пути, указанном в Python-программе. Эта часть пути должна быть явно преобразована в фактический путь с помощьюos.path.expanduser
. См. Почему я вынужден использовать os.path.expanduser в python? и os.makedirs не понимает “~” в моем пути. -
Имейте в виду, что
os.listdir
вернет только имена файлов, а не пути. Попытка перебрать директорию, перечисленную таким образом, будет работать, только если эта директория является текущим рабочим каталогом. -
Также важно убедиться в фактическом имени файла. Windows имеет опцию скрытия расширений имен файлов в графическом интерфейсе. Если вы видите
foo.txt
в окне, может быть, что фактическое имя файла являетсяfoo.txt.txt
или что-то другое. Вы можете отключить эту опцию в своих настройках. Вы также можете проверить имя файла с помощью командной строки;dir
расскажет вам правду о том, что находится в папке. (Эквивалентом в Linux/Mac, конечно, являетсяls
, но эта проблема не должна возникать там с самого начала.) -
Обратные слэши в обычных строках являются управляющими последовательностями. Это вызывает проблемы, когда вы пытаетесь использовать обратный слэш в качестве разделителя пути на Windows. Однако использование обратных слешей для этого не обязательно и в целом не рекомендуется. Смотрите Как мне следует писать путь Windows в строковом литерале Python?.
-
Когда вы пытаетесь создать новый файл, используя режим файла, такой как
w
, путь к новому файлу все еще должен существовать — то есть все промежуточные папки. См., например, Попытка использовать open(filename, ‘w’) приводит к IOError: [Errno 2] No such file or directory, если каталог не существует. Также помните, что имя нового файла должно быть допустимым. В частности, не получится попытаться вставить дату в форматеMM/DD/YYYY
в имя файла, так как/
будет восприниматься как разделитель пути.
Убедитесь, что все папки в пути к файлу существуют.
Я получал эту ошибку, потому что мне было не очевидно, создается ли папка или нет, потому что, в теории, функция, вызываемая в коде, должна была это сделать.
import os
file_path = input('Введите путь к файлу')
dir_path = os.path.dirname(file_path)
os.makedirs(dir_path, exist_ok=True)
with open(file_path) as file:
file.write("Записано!")
В случае OP он только читает файл, так что он должен существовать в указанном им пути. Возможно, мы забываем флаг w
для функции open (например, open('/path/to/file', 'w')
) и в итоге получаем эту ошибку.
(для Pycharm)
Pycharm имеет встроенные настройки “Активного Каталога”
Вы можете получить эту ошибку при изменении имени папки, потому что эта настройка не обновляется. Чтобы исправить эту ошибку в Pycharm, выберите “Изменить конфигурации” (в правом верхнем углу окна рядом с кнопкой запуска).
Затем измените как путь к скрипту (если вы еще не сделали это), так и папку рабочего каталога.
Проверьте указанный путь, является ли он абсолютным или относительным.
Если это что-то вроде –>/folder/subfolder/file
–>Компьютер будет искать папку в корневом каталоге.
Если это что-то вроде –> ./folder/subfolder/file
–> Компьютер будет искать папку в текущем рабочем каталоге.
Если вы используете IDE, такую как VScode, убедитесь, что вы открыли IDE из того же каталога, где находится файл, к которому вы хотите получить доступ.
Например, если вы хотите получить доступ к file.txt, который находится в разделе “Документы”, попробуйте открыть IDE из Документов, щелкнув правой кнопкой мыши в каталоге и выбрав “Открыть с помощью “
Один (из многих) возможный сценарий сбоя:
- если целевой файл является символической ссылкой и вы получили ссылку, например, с помощью
os.scandir()
,os.listdir()
и т. д. и затем попытались вызвать.stat()
на поврежденной символической ссылке, то вызовstat()
будет пытаться выполниться на несуществующей символической ссылке цели, а не на самой символической ссылке.
По умолчанию .stat()
вызывается с .stat(*, follow_symlinks=True)
; используйте .stat(follow_symlinks=False)
, чтобы предотвратить следование (поврежденным) символическим ссылкам.
Это сработало для меня, это сработает и для вас.
# получить текущий рабочий каталог
os.getcwd()
# обрезать до каталога, который вы хотите, и получить 0-й элемент из split
os.getcwd().split(dir_in_str)[0]
# перечислить файлы и каталоги внутри dir
os.listdir(dir_in_str)
# добавить независимый от окружения разделитель пути
path = path + f'{os.path.sep}'
# поиск, содержится ли строка или заканчивается на path
if str in path:
Счастливого кодирования.. 😉
В моем случае это сработало. Я использовал json, который находился в каталоге rest_api в моей директории проекта.
После этого я изменил от этого
f = open('rest_api/contacts0.json')
до
f = open('../rest_api/contacts0.json')
После добавления ../ он смог прочитать файл.
Ответ или решение
Ошибка FileNotFoundError / IOError: ‘[Errno 2] No such file or directory’ при использовании функции open() в Python
При работе с файлами в Python функция open()
может вернуть ошибку FileNotFoundError
или IOError
, что указывает на то, что файл не может быть найден. В данном случае вы пытаетесь открыть файл recentlyUpdated.yaml
и получаете ошибку, подобную следующей:
IOError: [Errno 2] No such file or directory: 'recentlyUpdated.yaml'
Эта ошибка возникает из-за того, что Python не может найти файл по указанному пути. Рассмотрим подробнее, как работает поиск файлов в Python и какие шаги можно предпринять для устранения этой проблемы.
Основы поиска файлов в Python
Когда вы вызываете open('recentlyUpdated.yaml')
, вы передаете относительный путь. Это значит, что Python ищет файл относительно текущей рабочей директории (CWD, Current Working Directory). При этом важно понимать, что рабочая директория не всегда совпадает с местоположением скрипта.
Проверка существования файла
Для начала убедитесь, что файл действительно существует, и у него правильное расширение. Один из простых способов это сделать — использовать метод os.listdir()
, чтобы просмотреть список файлов в текущей директории:
import os
print(os.listdir(os.getcwd())) # Печатает список файлов в текущей рабочей директории
Также вы можете проверить, где находится рабочая директория, вызвав os.getcwd()
:
import os
print(os.getcwd()) # Печатает текущую рабочую директорию
Если файл не находится в указанной директории, у вас есть несколько вариантов решения проблемы:
Решения проблемы
- Использование абсолютного пути:
Укажите полный путь к файлу. Это самый надежный способ избежать проблем с относительными путями.
file = open(r'C:\path\to\your\recentlyUpdated.yaml')
- Изменение текущей рабочей директории:
Вы можете изменить текущую рабочую директорию с помощью методаos.chdir()
, указав директорию, в которой находится ваш файл:
import os
os.chdir(r'C:\path\to\your\directory')
file = open('recentlyUpdated.yaml') # Теперь Python будет искать файл в новой рабочей директории
- Использование метода pathlib:
Вы можете создать путь к файлу относительно скрипта, используя библиотекуpathlib
, которая более удобна для работы с путями:
from pathlib import Path
script_location = Path(__file__).absolute().parent
file_location = script_location / 'recentlyUpdated.yaml'
file = file_location.open()
Дополнительно о путях
При указании путей всегда помните о следующих важных моментах:
- Обратные слэш: В строках на Windows, если используется обратный слэш
\
, нужно использовать "сырые строки" (raw strings), чтобы избежать случайного распознавания escape-последовательностей. Например:
path = r'C:\Users\Username\recentlyUpdated.yaml' # Правильный способ
-
Проблемы с расширениями файлов: В Windows расширения файлов могут быть скрыты. Убедитесь, что файл действительно называется
recentlyUpdated.yaml
, а не, например,recentlyUpdated.yaml.yaml
илиrecentlyUpdated
без расширения. -
Символьные ссылки: Если файл является символьной ссылкой и вы пытаетесь получить доступ к недоступному объекту, Python также может выдать ошибку.
Заключение
Ошибка FileNotFoundError
при использовании функции open()
чаще всего связана с неправильным указанием пути к файлу. Тщательно проверьте текущую рабочую директорию, убедитесь в правильности имен файлов и их расширений, а также рассмотрите возможность использования абсолютного пути или изменения текущей директории, чтобы решить проблему. Надеюсь, эта информация поможет вам успешно работать с файлами в Python.