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


У меня есть текстовый файл с ключевыми словами, и я использую

with open('filename.txt','r') as file:
    list_of_words = [x.strip('n') for x in file.readlines()

Я получаю: UnicodeDecodeError: кодек 'ascii' не может декодировать байт 0xc4 в позиции 5595: порядковый номер не в диапазоне (128) в строке 2

Я понимаю ошибку. Я не понимаю, почему это на линии 2.

Согласно python docs: https://docs.python.org/3/library/functions.html#open

В текстовом режиме (по умолчанию, или когда 't' включен в режим аргумент), содержание файл возвращается в виде str, байт будучи впервые декодированы с использованием платформо-зависимого кодирования или с использованием указанная кодировка, если она задана.

Это означает, что при открытии файла процесс декодирования происходит при открытии файла и возвращается в переменной "file".

Тогда почему я получаю ошибку в строке 2?

4 2

4 ответа:

Вы, кажется, путаете Объект file возвращается вызовом open() для фактического процесса чтения из объекта file.

Python декодируетсодержимое файла, как вы его читаете. Открытие объекта file не считывает данные из файла, а просто создает объект file . В этот момент данные из файла не считываются, в Python нет байтов для обработки пока.

В строке 2 вы фактически читаете из файла, используя метод file.readlines(). Этотот метод , который говорит файловому объекту извлекать данные из файловой системы (байты) и декодировать эти байты. Только тогда Python может знать, что данные на самом деле не могут быть декодированы как ASCII.

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

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

Только когда вы звоните readlines, read, Выполните итерацию по файлу или иным образом считайте из файла, который вы фактически получаете содержимое, первоначально в виде байтов. Эти байты затем декодируются, и только тогда обнаруживается, что они не являются допустимыми в указанной кодировке.

Если вы не указываете кодировка, python угадывает ее из конфигурации операционной системы :

encoding это имя кодировки, используемой для декодирования или кодирования (...). Кодировка по умолчанию зависит от платформы(независимо от локали.getpreferredencoding () возвращает)

Похоже, что в вашей системе locale.getpreferredencoding() возвращает ASCII, и файл не закодирован в ASCII.

Просто укажите правильную кодировку:

with open('filename.txt', 'r', encoding='utf-8') as file:
    list_of_words = [line.strip('\n') for line in file]

На самом деле это просто плохо сформулированное объяснение в документации. Функция Open не читает никакого содержимого, она только возвращает дескриптор файла с указанным режимом и кодировкой, который был передан ей из ОС.