Кодировка символов в Python

PythonPythonBeginner
Практиковаться сейчас

Введение

В этой лабораторной работе вы получите полное представление о кодировании символов в Python. Мы начнем с изучения истории и основных концепций кодирования символов, от ограничений ранних кодировок, таких как ASCII и страновые кодировки ANSI, до разработки и важности стандарта Unicode и его различных реализаций, таких как UTF-8. Вы узнаете, как проверить кодировку по умолчанию в вашей среде Python.

Опираясь на эту основу, вы изучите практические методы работы с кодированием символов в Python. Это включает использование функций ord() и chr() для преобразования между символами и их целочисленными представлениями, а также освоение методов encode() и decode() для преобразования между строками и байтами. Наконец, вы узнаете, как эффективно обрабатывать потенциальные ошибки кодирования, которые могут возникнуть в процессе декодирования, обеспечивая надежную и стабильную обработку текста в ваших приложениях Python.

Это Guided Lab, который предоставляет пошаговые инструкции, чтобы помочь вам учиться и практиковаться. Внимательно следуйте инструкциям, чтобы выполнить каждый шаг и получить практический опыт. Исторические данные показывают, что это лабораторная работа уровня начальный с процентом завершения 88%. Он получил 98% положительных отзывов от учащихся.

Изучение истории и концепций кодирования символов

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

Изначально компьютеры разрабатывались в США, что привело к созданию кодировки ASCII. ASCII использует один байт для представления символов и включает английские буквы, цифры и символы, всего 128 символов.

По мере того как компьютеры становились более распространенными во всем мире, ASCII оказалась недостаточной для представления символов из других языков. Это привело к разработке различных страновых кодировок, таких как GB2312, GBK, Big5 и Shift_JIS. Их часто совместно называли кодировками ANSI.

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

Существует несколько схем кодирования, реализующих Unicode, включая UCS4, UTF-8, UTF-16 и UTF-32. Среди них UTF-8 широко используется благодаря своей обратной совместимости с ASCII.

В Python 3 кодировкой по умолчанию является UTF-8, что позволяет напрямую использовать символы из различных языков, включая символы с диакритикой и символы. В более старых версиях, таких как Python 2, вам обычно приходилось указывать кодировку в начале скрипта, используя комментарии вроде ## -*- coding: UTF-8 -*- или ## coding=utf-8.

Вы можете проверить кодировку по умолчанию в вашей среде Python, используя модуль sys.

Сначала откройте интегрированный терминал в WebIDE, нажав Terminal -> New Terminal.

Затем запустите интерактивный интерпретатор Python, набрав python и нажав Enter.

python

Вы должны увидеть вывод, похожий на этот:

Python 3.10.x (main, ...)
[GCC ...] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

Теперь импортируйте модуль sys и проверьте кодировку по умолчанию:

import sys
sys.getdefaultencoding()

Вывод покажет кодировку по умолчанию, которая обычно является utf-8 в Python 3.

>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
>>>

Выйдите из интерпретатора Python, набрав exit() и нажав Enter.

exit()

Использование ord() и chr() для преобразования символов и целых чисел

На этом этапе мы научимся использовать встроенные функции Python ord() и chr() для преобразования между символами и их соответствующими целочисленными представлениями в Unicode.

В Python 3 строки представлены с использованием Unicode. Функция ord() принимает один символ в качестве входных данных и возвращает его соответствующее десятичное целочисленное значение Unicode.

Давайте создадим новый файл Python для экспериментов с этими функциями. В WebIDE щелкните правой кнопкой мыши на каталоге project в обозревателе файлов и выберите New File. Назовите файл char_conversion.py.

Откройте char_conversion.py в редакторе и добавьте следующий код:

## Используйте ord() для получения десятичного значения Unicode символов
char1 = 'a'
char2 = 'é'
char3 = ';'

print(f"Десятичное значение Unicode для '{char1}' равно: {ord(char1)}")
print(f"Десятичное значение Unicode для '{char2}' равно: {ord(char2)}")
print(f"Десятичное значение Unicode для '{char3}' равно: {ord(char3)}")

Сохраните файл, нажав Ctrl + S (или Cmd + S на macOS).

Теперь снова откройте интегрированный терминал (если он еще не открыт) и запустите скрипт с помощью команды python:

python char_conversion.py

Вы должны увидеть вывод, похожий на этот:

Десятичное значение Unicode для 'a' равно: 97
Десятичное значение Unicode для 'é' равно: 233
Десятичное значение Unicode для ';' равно: 59

Функция chr() выполняет обратную операцию. Она принимает десятичное целое число (или шестнадцатеричное целое число), представляющее кодовую точку Unicode, и возвращает соответствующий символ.

Давайте добавим больше кода в char_conversion.py для использования функции chr(). Добавьте следующие строки к существующему коду:

## Используйте chr() для получения символа из десятичного значения Unicode
int1 = 8364
int2 = 8482

print(f"Символ для десятичного значения Unicode {int1} это: {chr(int1)}")
print(f"Символ для десятичного значения Unicode {int2} это: {chr(int2)}")

## Вы также можете использовать шестнадцатеричные значения с chr()
hex_int = 0x00A9 ## Шестнадцатеричное представление символа '©'
print(f"Символ для шестнадцатеричного значения Unicode {hex(hex_int)} это: {chr(hex_int)}")

Снова сохраните файл.

Запустите скрипт из терминала:

python char_conversion.py

Теперь вывод должен включать результаты работы функции chr():

Десятичное значение Unicode для 'a' равно: 97
Десятичное значение Unicode для 'é' равно: 233
Десятичное значение Unicode для ';' равно: 59
Символ для десятичного значения Unicode 8364 это: €
Символ для десятичного значения Unicode 8482 это: ™
Символ для шестнадцатеричного значения Unicode 0xa9 это: ©

Возможно, вы задаетесь вопросом, как найти шестнадцатеричное представление символа Unicode. Вы можете использовать функцию ord() для получения десятичного значения, а затем встроенную функцию hex() для преобразования десятичного значения в его шестнадцатеричное строковое представление.

Добавьте следующий код в char_conversion.py:

## Преобразование символа в его шестнадцатеричное представление Unicode
char_copyright = '©'
decimal_copyright = ord(char_copyright)
hexadecimal_copyright = hex(decimal_copyright)

print(f"Шестнадцатеричное значение Unicode для '{char_copyright}' равно: {hexadecimal_copyright}")

Сохраните файл и запустите его в последний раз:

python char_conversion.py

Окончательный вывод будет включать шестнадцатеричное значение для символа '©':

Десятичное значение Unicode для 'a' равно: 97
Десятичное значение Unicode для 'é' равно: 233
Десятичное значение Unicode для ';' равно: 59
Символ для десятичного значения Unicode 8364 это: €
Символ для десятичного значения Unicode 8482 это: ™
Символ для шестнадцатеричного значения Unicode 0xa9 это: ©
Шестнадцатеричное значение Unicode для '©' равно: 0xa9

Это демонстрирует, как ord(), chr() и hex() могут использоваться вместе для работы с кодировками символов в Python.

Преобразование между строками и байтами с помощью encode() и decode()

На этом этапе мы научимся преобразовывать строки Python (которые являются Unicode) в объекты байтов и обратно, используя методы encode() и decode(). Это необходимо при работе с данными, которые должны передаваться или храниться в определенном формате кодирования.

Метод encode() используется для преобразования строки в объект байтов с использованием указанной кодировки. Он возвращает объект bytes.

Создадим новый файл Python с именем encoding_decoding.py в каталоге ~/project.

Откройте encoding_decoding.py в редакторе и добавьте следующий код:

## Определяем строку
my_string = 'café'

## Кодируем строку с использованием UTF-8
encoded_utf8 = my_string.encode('utf-8')

## Кодируем строку с использованием Latin-1
encoded_latin1 = my_string.encode('latin-1')

## Выводим закодированные объекты байтов
print(f"Исходная строка: {my_string}")
print(f"Закодировано в UTF-8: {encoded_utf8}")
print(f"Закодировано в Latin-1: {encoded_latin1}")

Сохраните файл.

Теперь запустите скрипт из интегрированного терминала:

python encoding_decoding.py

Вы должны увидеть вывод, показывающий исходную строку и ее байтовое представление как в UTF-8, так и в Latin-1:

Original string: café
Encoded in UTF-8: b'caf\xc3\xa9'
Encoded in Latin-1: b'caf\xe9'

Обратите внимание, что вывод для объектов байтов начинается с b', что указывает на то, что это литералы байтов. Шестнадцатеричные числа представляют последовательности байтов для строки в каждой кодировке.

Метод decode() используется для преобразования объекта байтов обратно в строку с использованием указанной кодировки.

Добавим код в encoding_decoding.py для декодирования созданных нами объектов байтов. Добавьте следующие строки к существующему коду:

## Декодируем объекты байтов обратно в строки
decoded_utf8 = encoded_utf8.decode('utf-8')
decoded_latin1 = encoded_latin1.decode('latin-1')

## Выводим декодированные строки
print(f"Декодировано из UTF-8: {decoded_utf8}")
print(f"Декодировано из Latin-1: {decoded_latin1}")

Сохраните файл.

Запустите скрипт снова:

python encoding_decoding.py

Теперь вывод покажет исходную строку, успешно декодированную как из байтов UTF-8, так и из байтов Latin-1:

Original string: café
Encoded in UTF-8: b'caf\xc3\xa9'
Encoded in Latin-1: b'caf\xe9'
Decoded from UTF-8: café
Decoded from Latin-1: café

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

Обработка ошибок кодирования при декодировании

На этом этапе мы рассмотрим, что происходит при попытке декодировать байты с использованием неправильной кодировки, и как обрабатывать такие ошибки.

Как мы видели на предыдущем шаге, для успешного декодирования байтов необходимо знать исходную кодировку, использованную для создания этих байтов. Если вы попытаетесь декодировать байты с несовместимой кодировкой, Python вызовет ошибку.

Давайте изменим наш файл encoding_decoding.py, чтобы продемонстрировать это. Откройте файл в редакторе и добавьте следующий код в конец:

## Попытка декодировать байты, закодированные в Latin-1, с использованием ASCII
try:
    decoded_incorrectly = encoded_latin1.decode('ascii')
    print(f"Декодировано из Latin-1 с использованием ASCII: {decoded_incorrectly}")
except UnicodeDecodeError as e:
    print(f"Ошибка при декодировании Latin-1 с использованием ASCII: {e}")

Сохраните файл.

Запустите скрипт из терминала:

python encoding_decoding.py

Теперь вывод будет включать сообщение об ошибке при попытке декодировать байты Latin-1 с помощью ASCII:

Original string: café
Encoded in UTF-8: b'caf\xc3\xa9'
Encoded in Latin-1: b'caf\xe9'
Decoded from UTF-8: café
Decoded from Latin-1: café
Error decoding Latin-1 with ASCII: 'ascii' codec can't decode byte 0xe9 in position 3: ordinal not in range(128)

UnicodeDecodeError указывает на то, что кодек ASCII столкнулся с байтами, которые не являются допустимыми согласно стандарту ASCII. В данном случае байт 0xe9 является представлением символа 'é' в кодировке Latin-1, но это не допустимый символ ASCII (ASCII охватывает только символы с 0 по 127).

При декодировании вы также можете указать, как обрабатывать ошибки, используя параметр errors метода decode(). Распространенные стратегии обработки ошибок включают:

  • 'strict' (по умолчанию): Вызывает UnicodeDecodeError.
  • 'ignore': Игнорирует не подлежащие декодированию байты.
  • 'replace': Заменяет не подлежащие декодированию байты замещающим символом (обычно ``).
  • 'xmlcharrefreplace': Заменяет не подлежащие декодированию байты ссылками на XML-символы.

Давайте добавим примеры использования стратегий обработки ошибок 'ignore' и 'replace' в encoding_decoding.py. Добавьте следующий код:

## Попытка декодировать байты, закодированные в Latin-1, с использованием ASCII с обработкой ошибок
decoded_ignore = encoded_latin1.decode('ascii', errors='ignore')
decoded_replace = encoded_latin1.decode('ascii', errors='replace')

print(f"Декодировано из Latin-1 с использованием ASCII (игнорировать ошибки): {decoded_ignore}")
print(f"Декодировано из Latin-1 с использованием ASCII (заменить ошибки): {decoded_replace}")

Сохраните файл.

Запустите скрипт снова:

python encoding_decoding.py

Теперь вывод покажет результаты с обработкой ошибок:

Original string: café
Encoded in UTF-8: b'caf\xc3\xa9'
Encoded in Latin-1: b'caf\xe9'
Decoded from UTF-8: café
Decoded from Latin-1: café
Error decoding Latin-1 with ASCII: 'ascii' codec can't decode byte 0xe9 in position 3: ordinal not in range(128)
Decoded from Latin-1 using ASCII (ignore errors): caf
Decoded from Latin-1 using ASCII (replace errors): caf

Как вы можете видеть, 'ignore' приводит к "caf", поскольку недопустимый байт был проигнорирован, удалив символ 'é'. 'replace' заменяет недопустимый байт замещающим символом ``, в результате чего получается "caf".

Выбор подходящей стратегии обработки ошибок зависит от ваших конкретных потребностей. В большинстве случаев во время разработки лучше использовать 'strict', чтобы на ранних этапах выявлять проблемы с кодированием. В производственной среде вы можете выбрать 'replace' или 'ignore', если вам нужно обрабатывать данные с потенциальными проблемами кодирования, но помните, что это может привести к потере или повреждению данных.

Резюме

В этой лабораторной работе мы изучили историю и основные концепции кодирования символов, начиная с ASCII и его ограничений, которые привели к разработке различных страновых кодировок и, в конечном итоге, к стандарту Unicode. Мы узнали, что Unicode предоставляет уникальный код для каждого символа и реализуется различными схемами кодирования, такими как UTF-8, которая является кодировкой по умолчанию в Python 3 и обратно совместима с ASCII. Мы также научились проверять кодировку по умолчанию в Python с помощью модуля sys.

Затем мы практиковались в преобразовании между символами и их целочисленными представлениями с использованием функций ord() и chr(), а также между строками и байтами с использованием методов encode() и decode(). Наконец, мы рассмотрели, как обрабатывать потенциальные ошибки кодирования, которые могут возникнуть в процессе декодирования.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.