Обработка ошибок ввода вывода в Python: от FileNotFoundError до OSError

Раздел: Python -> Ошибки и исключения

Ошибка ввода вывода в Python: причины и обработка

Ошибка ввода вывода (IOError) в Python возникает при сбоях операций с файлами, сетью или устройствами. В Python 3 IOError объединен с OSError, а конкретные ситуации представлены подклассами FileNotFoundError, PermissionError, IsADirectoryError и другими. Основной способ обработки - конструкция try/except.

Наиболее эффективное решение: перехват конкретных исключений

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

try:
    with open('data.txt', 'r') as f:
        content = f.read()
except FileNotFoundError:
    print('Файл не найден. Создайте его или укажите другой путь.')
except PermissionError:
    print('Нет прав на чтение файла.')
except IsADirectoryError:
    print('Указанный путь является директорией, а не файлом.')

Client error python (ошибка http-клиента в python)

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

Варианты решений

Как избежать ошибки при открытии несуществующего файла?

Проверить существование файла перед открытием с помощью os.path.exists или pathlib.Path.exists.

import os

filename = 'config.json'
if os.path.exists(filename):
    with open(filename) as f:
        data = f.read()
else:
    print('Файл отсутствует. Будет использован стандартный конфиг.')

No installed python found (python не найден в системе)

Как гарантировать закрытие файла даже при ошибке?

Использовать менеджер контекста with. Он автоматически закрывает файл при любом завершении блока.

with open('log.txt', 'a') as log:
    log.write('Запись операции\n')
# Файл закрыт даже если write вызвал исключение

Python traceback using (трассировка ошибок в python)

Как различить разные причины ошибок ввода вывода?

Проверять код ошибки через атрибут errno или использовать цепочку except.

import errno

try:
    with open('/etc/passwd', 'w') as f:
        f.write('test')
except OSError as e:
    if e.errno == errno.EACCES:
        print('Отказано в доступе.')
    elif e.errno == errno.ENOENT:
        print('Файл не найден.')
    else:
        print('Неизвестная ошибка ввода вывода.')

Python pip not found (ошибка 'pip not found' в python)

Как исправить ошибку кодировки при чтении текстового файла?

Указать правильную кодировку в параметре encoding.

try:
    with open('data.txt', 'r', encoding='utf-8') as f:
        text = f.read()
except UnicodeDecodeError:
    # Попробовать другую кодировку
    with open('data.txt', 'r', encoding='cp1251') as f:
        text = f.read()

Unable to locate package python (ошибка 'unable to locate package' в python)

Как обрабатывать ошибки при прямом системном вводе выводе?

При использовании низкоуровневых функций (os.open, os.read) необходимо перехватывать OSError.

import os

fd = os.open('/proc/uptime', os.O_RDONLY)
try:
    data = os.read(fd, 100)
    print(data.decode())
except OSError as e:
    print(f'Системная ошибка: {e}')
finally:
    os.close(fd)

Типичные проблемы и их решения

Слишком общее исключение: ловля except Exception скрывает неожиданные сбои. Следует перехватывать только нужные подклассы.

Игнорирование ошибок: пустой блок except (pass) может привести к незаметной потере данных. Лучше логировать проблему или хотя бы выводить предупреждение.

Проблемы с путями: относительные пути зависят от текущей рабочей директории. Используйте абсолютные пути или os.path.join.

Блокировка файлов: на Windows файл может быть заблокирован другим процессом. Проверьте, не открыт ли файл в другой программе, и обработайте PermissionError.

- Io error python (ошибка ввода-вывода в python)
- ошибка компиляции python (ошибка компиляции (синтаксиса) в python)
- Python traceback (трассировка стека в python)

Расширенные примеры обработки ошибок ввода вывода

Работа с несколькими файлами и журналирование ошибок

Пример
import sys
import logging

logging.basicConfig(level=logging.ERROR)

files = ['source.txt', 'backup.txt', 'config.ini']
results = {}

for fname in files:
    try:
        with open(fname, 'r') as f:
            results[fname] = f.readline().strip()
    except FileNotFoundError:
        logging.error(f'{fname} не найден')
    except PermissionError:
        logging.error(f'Нет доступа к {fname}')
    except OSError as e:
        logging.error(f'Ошибка при работе с {fname}: {e}')

print(results)
{'source.txt': 'строка из source', 'config.ini': 'настройка 1'}

Безопасная запись с обработкой ошибок

Пример
import tempfile

output_path = 'output.txt'
try:
    # Создаем временный файл для атомарной записи
    with tempfile.NamedTemporaryFile(mode='w', delete=False, dir='.') as tmp:
        tmp.write('Временные данные')
        tmp_name = tmp.name
    # Переименовываем временный файл в целевой
    import shutil
    shutil.move(tmp_name, output_path)
except OSError as e:
    print(f'Не удалось записать файл: {e}')
    # В случае ошибки временный файл можно удалить
    if tmp_name:
        os.unlink(tmp_name)
(файл output.txt создан успешно)

Пользовательское исключение для ошибок ввода вывода

Пример
class FileReadError(Exception):
    """Пользовательское исключение для проблем чтения файла."""
    def __init__(self, filename, original_exception):
        self.filename = filename
        self.original = original_exception
        super().__init__(f'Ошибка чтения {filename}: {original_exception}')

def safe_read(filename):
    try:
        with open(filename) as f:
            return f.read()
    except OSError as e:
        raise FileReadError(filename, e)

try:
    safe_read('missing.txt')
except FileReadError as e:
    print(e)
Ошибка чтения missing.txt: [Errno 2] No such file or directory: 'missing.txt'

Повторная попытка при временной ошибке

Пример
import time
from random import random

def retry_read(path, attempts=3, delay=1):
    for i in range(attempts):
        try:
            with open(path) as f:
                return f.read()
        except OSError as e:
            if i == attempts - 1:
                raise
            time.sleep(delay * (i + 1))
    return None

try:
    content = retry_read('unstable.txt', attempts=5, delay=0.5)
    print('Содержимое прочитано')
except OSError:
    print('Не удалось прочитать файл после нескольких попыток')
(если файл наконец становится доступен, выводится сообщение об успехе)

Ошибка ввода-вывода в Python - comments

En
Io error python (python)