Определение кодировки строки в Python: Unicode vs ASCII

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Если вам нужно проверить, состоит ли строка только из символов ASCII в Python 3.7+, просто используйте метод str.isascii():

Python
Скопировать код
def is_ascii(s):
    return s.isascii()

# Пример применения
print(is_ascii("ASCII"))       # Возвратит "True", что ожидаемо
print(is_ascii("Únícodę"))    # Возвратит "False", это не ASCII, а Unicode!

Этот встроенный метод является быстрым и надёжным способом — он возвращает True, если строка содержит только символы ASCII, в противном случае — False.

Кинга Идем в IT: пошаговый план для смены профессии

Типы строк и их идентификация

В Python 3 все строки по умолчанию типа Unicode, хотя могут содержать исключительно символы ASCII, а также смешанные строки из символов ASCII и Unicode. Для определения типов строк и объектов используется функция isinstance().

Определение строк Unicode

Функция isinstance(obj, str) позволяет установить, является ли данный объект строкой Unicode:

Python
Скопировать код
def is_unicode_string(obj):
    return isinstance(obj, str)  # Вопрос: перед нами строка или нет?

Различение bytearray

Bytearray — это обобщенный тип данных, способный хранить в себе ASCII, Unicode строки или произвольные байты. Для их определения используйте isinstance(obj, bytes):

Python
Скопировать код
def is_bytestring(obj):
    return isinstance(obj, bytes)  # У нас на руках bytearray?

Декодирование bytearray

Для расшифровки bytearray в заданной кодировке применяется метод .decode():

Python
Скопировать код
def decode_bytestring(byte_data, encoding='utf-8'):
    try:
        return byte_data.decode(encoding)  # Успешное переведение байт в текст
    except UnicodeDecodeError:
        return None  # В противном случае придется смириться с неизвестностью

Совместимость Python 2 и Python 3

Python 2, несмотря на отставку от активного использования, по-прежнему встречается в наследуемом коде и требует определенных усилий для поддержки.

Проверка строк в Python 2

В Python 2 существовали два отдельных типа строк: ASCII строки типа str и Unicode строки типа unicode. Для проверки используйте isinstance(x, basestring):

Python
Скопировать код
def is_string_in_python2(x):
    return isinstance(x, basestring)  # Стоит ли перед нами строка?

Переключение между Python 2 и 3

Если вы не уверены в версии Python:

Python
Скопировать код
try:
    unicode_data = byte_data.decode('utf-8')  # У нас есть расшифрованные данные!
except AttributeError:
    unicode_data = byte_data  # Это ASCII данные, преобразование не требуется

Преобразование байтов в Unicode: когда это необходимо?

Преобразование из bytes в Unicode — это сложная задача. Важно понимать, что не всегда байтовые данные нужно преобразовывать в Unicode. Рассматривайте каждый конкретный случай отдельно:

Python
Скопировать код
if is_bytestring(data): 
    text = decode_bytestring(data)  # Превращаем байты в текст, если это необходимо

Визуализация

Можно рассмотреть проверку строки на соответствие ASCII или Unicode как процесс сортировки почты:

Markdown
Скопировать код
Почтовый ящик (📬): Принимает только конверты стандартного размера

ASCII (🔠): Обычные конверты проходят без проблем
Unicode (🔤): Может быть разного размера и формата, не все конверты могут влезть

В качестве примера возьмем строку:

Python
Скопировать код
s = "Hello, World!"  # Вот и наше послание
Markdown
Скопировать код
📬 Сможет ли оно пройти?
  – Да 👉 Это ASCII конверт! (🔠)
  – Нет 👉 Значит, это Unicode посылка! (🔤)

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

Кодирование и декодирование строк: подход Python

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

Кодирование с помощью .encode()

Метод .encode() приводит строку к байтовому виду при необходимости:

Python
Скопировать код
unicode_string = "Hello, Unicode!"
byte_string = unicode_string.encode('utf-8')  # Преобразуем строку в байты

Декодирование с помощью .decode()

И наоборот, метод .decode() преобразует байтовую строку обратно в читаемую Unicode строку:

Python
Скопировать код
recovered_string = byte_string.decode('utf-8')  # Байты обратно преобразованы в текст

Избегая ошибок при проверке типа

Не рекомендуется использовать сравнение type(x) == y — это может быть источником ошибок. Лучшим выбором всегда будет функция isinstance().

Полезные материалы

  1. Unicode HOWTO — Документация Python 3.12.2 — подробное руководство по работе с Unicode в Python.
  2. Как определить, что строка в Python это ASCII? – Stack Overflow — полезные советы от сообщества разработчиков Python.
  3. Встроенные функции — Документация Python 3.12.2 — всё о функции isinstance().
  4. chardet · PyPI — библиотека для определения кодировки данных.
  5. Минимум, который должен знать каждый программист о Unicode и наборах символов — Joel on Software — базовые понятия о Unicode для разработчиков.
  6. Что должен знать каждый программист о кодировках и наборах символов — прекрасное объяснение принципов работы с кодировками.
  7. Основные Типы — Документация Python 3.12.2 — детальный обзор функций кодирования и декодирования строк.