Руководство разработчика Python по кодировке символов
Кодирование символов - распространенная проблема при разработке программного обеспечения. Как и в других языках программирования, кодирование символов в Python может быть проблематичным. В этой статье мы углубимся в кодировку символов, обсудим способы взаимодействия с текстом и байтами в вашем проекте Python 3 и исправим распространенные ошибки кодирования, используя кодировку символов в Python 3.
Кодировка символов
На человеческом языке текстовые файлы на компьютере содержат набор символов, составленных из текста или предложений, которые могут включать английский текст "a
” или латинский текст ”ā
”. Однако на компьютерном языке этот текстовый файл содержит биты и байты, а не текст. Подобно английскому или латыни, компьютер хранит символы в виде байтов. Эти байты больше похожи на компьютерные коды, которые переводятся в удобочитаемый текст. Этот перевод представляет собой кодировку символов.
Кодировка символов — это набор методов для преобразования необработанных двоичных файлов (0101110110) в читаемые символы (текст) с использованием таблицы поиска кодировки. Каждому символу присваивается уникальный идентификационный номер, который помогает компьютерам читать и понимать текст. Для интерпретации байтов используются несколько типов кодировок символов. Часто при интерпретации байтов применяется неправильная кодировка символов, из-за чего они отображаются в виде странных символов, таких как voil
├Ā
‡å-ã
, или неизвестных символов, таких как ������; что еще хуже, это может вызвать ошибку, которая приведет к сбою вашей программы.
При работе с символами в Python вы столкнетесь с двумя основными типами данных: строками и байтами. Кодирование символов вращается вокруг кодирования и декодирования этих типов данных.
Строковый модуль
Строки - это компьютерные байты, интерпретируемые и отображаемые в удобочитаемой форме. До разработки Python 3 строки по умолчанию использовали двоичный формат для хранения байтов. Это подразумевает, что строки представляют собой байты с ASCII, заданной в качестве кодировки по умолчанию. Хотя ASCII был весьма полезен, он может кодировать только символы английского языка. Решение этой проблемы привело к разработке универсального стандарта кодирования Unicode. Unicode - это универсальный набор символов, который определяет все символы для различных человеческих языков, используемых на компьютерах с более чем миллионом кодовых точек. Эти кодовые точки относятся к отображаемому тексту или символам.
В Python 3 каждая строка по умолчанию использует формат Unicode для представления символов. Это подразумевает, что каждый текст имеет определенную кодовую точку, которая отображает символы, использующие UTF-8 в качестве кодировки по умолчанию.
Байты
Второй тип данных - это байты, которые представляют собой последовательность целых чисел. Байт - это набор из восьми битов, которые представляют единицу информации. Символы в компьютере включают текст или строки, состоящие из одного или нескольких байтов. Представьте, что вы получаете файл, содержащий данные в байтах. Вам нужно будет перевести эти байты в читаемый текст. В этом случае кодировка символов преобразует выбранный вами символ в правильные байты в памяти компьютера, прежде чем считывать байты обратно в символы для отображения текста.
Работа с кодировкой символов в Python
Как указывалось ранее, Python 3 имеет два типа данных: строки и байты. Процесс перемещения между строками и байтами известен как кодирование и декодирование в Python. Теперь давайте углубимся в то, как это работает.
Кодирование строк в байты
Процесс преобразования строк (текста) в компьютерные байты известен как кодирование. В Python 3 строки представляют собой удобочитаемый текст, представляющий собой символы Unicode. Unicode - это не кодировка, а абстрактный стандарт кодирования, который использует формат преобразования Unicode (UTF) для кодирования. Хотя существует несколько кодировок символов, мы будем работать с UTF-8, который является кодировкой по умолчанию для Python 3. UTF относится к стандартной кодировке Python, а 8 относится к 8-битным единицам, используемым в кодировке символов. UTF-8 - это стандартная и эффективная кодировка строк Unicode, которая представляет символы в одно-, двух-, трех- или четырехбайтовых единицах. Python по умолчанию использует UTF-8, что означает, что его не нужно указывать в каждом файле Python.
Чтобы закодировать строку в байты, добавьте метод encode
, который вернет двоичное представление строки.
>>> text = 'Hello World'
>>> text.encode('utf-8')
b'Hello Word'
Выходные данные представляют собой двоичное представление Hello
. Далее давайте посмотрим на что-то более сложное.
>>> text = 'parlé'
>>> text.encode('utf-8')
b'parl\xc3\xa9'
>>> text = 'résumé'
>>> text = text.encode('utf-8')
b'r\xc3\xa9sum\xc3\xa9'
В приведенном выше коде буквы «parl
» являются символами ASCII, что позволяет их представлять. Каждый символ в таблице ASCII представляет собой один байт. Однако сложные символы, такие как é
, несовместимы с ASCII в UTF-8 и представлены двумя закодированными байтами, xc3
и xa9
, как в первом примере. Во втором примере строки, не совместимые с ASCII, представлены тремя закодированными байтами. UTF-8 может кодировать до четырех байтов. Это означает, что сложные символы в UTF-8 требуют несколько байтов для их двоичного представления.
Декодирование байтов в строки
Преобразование байтового объекта в строку известно как декодирование. Чтобы декодировать байты в строки, вызовите метод decode()
и укажите тип кодировки символов, который вы хотите использовать. Конечно, мы используем UTF-8.
>>> text = b'parl\xc3\xa9'
>>> text.decode('utf-8')
'parlé'
>>> text = b'r\xc3\xa9sum\xc3\xa9'
>>> text.decode('utf-8)
'résumé'
Когда мы передаем двоичный формат вместе с методом декодирования, на выходе получается наша исходная строка.
- Помните, что вам не обязательно указывать UTF-8 при работе с Python 3. Мы указываем это здесь только для того, чтобы показать используемую кодировку.
Чтение текстового файла в Python
Файл на компьютере не содержит читаемого текста. Чтобы прочитать символы в файле как текст, вам необходимо использовать метод read()
. Кроме того, в Python, когда вы открываете файл для чтения или записи, лучше всего указывать кодировку символов, с которой вы работаете. Это связано с тем, что при работе с текстовыми файлами Python по умолчанию использует разные кодировки символов в зависимости от операционной системы. Обычно, когда вы открываете файл с помощью метода open()
, Python автоматически обрабатывает его как текстовый файл, чтобы преобразовать байты в текстовом файле в строку с нужной вам кодировкой. Лучше всего указать кодировку.
Вот пример:
>>> with open("data.txt", mode="r", encoding="utf-8") as f:
... message = f.read()
Написание текстового файла на Python
Вы также можете использовать метод open()
для записи файлов. Для записи установите его на запись, введя mode = w
:
>>> with open("data.txt", mode="w", encoding="utf-8") as f:
... f.write("Hi, I am having fun learning Python")
Другие кодировки, доступные в Python
Как упоминалось ранее, для символов Unicode в Python доступно несколько кодировок. Мы уже обсуждали UTF-8, который является наиболее распространенным и широко используемым. Это также кодировка по умолчанию для Python 3, но есть и другие:
UTF-16: кодировка UTF-16 для символов Unicode представляет символы в два или четыре байта. Наименьшее двоичное представление символа в UTF-16 состоит из двух байтов. Основное преимущество UTF-8 перед UTF-16 заключается в том, что первая использует один байт для кодирования символа ASCII, а вторая кодирует тот же символ двумя или более байтами. Английский текстовый файл в кодировке UTF-16 как минимум в два раза больше, чем версия того же файла в кодировке UTF-8.
UTF-32: UTF-32 использует фиксированные четыре байта для кодирования символов Unicode. Это означает, что каждая кодировка символов использует четыре байта. UTF-16 использует больше памяти по сравнению с UTF-8 и UTF-16. Это быстрее и предпочтительнее для манипуляций со строками, потому что вы можете вычислить длину строки в байтах, используя количество символов в строке. Однако для каждого символа ASCII вы используете дополнительные три байта.
Подводные камни и как их исправить
Избегайте ошибок кодирования символов любой ценой, так как они доставляют неудобства, и ни один разработчик не любит тратить время на исправление ошибки. Давайте рассмотрим распространенные ошибки при кодировании символов и способы исправления вероятных ошибок. Одной из распространенных ошибок, возникающих при работе с кодировкой символов в Python 3, является UnicodeEncodeError
. Есть несколько причин этой ошибки.
Во-первых, ошибка UnicodeEncodeError
может возникнуть при использовании символов, которые невозможно закодировать, например смайликов. Unicode поддерживает подавляющее большинство языков, но не все. Таким образом, символ, не поддерживаемый в Unicode, не будет работать. Во-вторых, когда strict
метод используется по умолчанию для кодирования и декодирования, это вызовет ошибку, если символ не может быть закодирован или декодирован.
Существует также ошибка UnicodeDecodeError
, которая возникает, когда кодировка символов байтов, которые мы читаем, и кодировка символов, которую Python пытается использовать для их чтения, не совпадают.
Как избежать или исправить эту ошибку?
Один из способов исправить ошибку кодировки символов - использовать метод ignore
или replace
для удаления специальных символов или эмодзи, которые не могут быть закодированы. Вы также можете использовать метод ignore
при открытии файла, чтобы избежать каких-либо ошибок. Вот пример:
text = 'ф'
with open('message.txt', 'w', encoding='utf-8', errors='ignore') as f:
f.write(text)
Заключение
Компьютеры не распознают текст; они хранят данные в двоичном формате. Кодировка символов - это ключ, который преобразует эти двоичные данные в читаемый текст. В этой статье мы обсудили несколько тем. Ранний метод кодирования символов, ASCII, был недостаточен, поскольку он не позволял представлять неанглийские символы в двоичном формате. Это было решено введением Unicode, который присваивал определенную кодовую точку каждому удобочитаемому символу. Мы также обсудили, как работает кодирование в Python 3 и различные методы кодирования символов в Python.