• en
  • Language: ru
  • Documentation version: 1.1.x

Юникод во Flask

Flask, как и Jinja2 и Werkzeug, полностью основан на Unicode, когда дело доходит до текста. Не только эти библиотеки, но и большинство связанных с веб библиотек Python, которые работают с текстом. Если вы до сих пор не знаете Unicode, вам, вероятно, следует прочитать The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets. Эта часть документации просто пытается охватить самые основы, чтобы у вас был приятный опыт работы с вещами, связанными с Unicode.

Автоматическое преобразование

Flask имеет несколько предположений о вашем приложении (которые вы, конечно, можете изменить), которые обеспечивают базовую и безболезненную поддержку Unicode:

  • кодировка текста на вашем сайте - UTF-8

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

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

Что это значит для вас?

HTTP основан на байтах. Не только протокол, но и система, используемая для адресации документов на серверах (так называемые URI или URL). Однако HTML, который обычно передается поверх HTTP, поддерживает большое разнообразие наборов символов, и какие из них используются, передаются в HTTP-заголовке. Чтобы не усложнять эту задачу, Flask просто предполагает, что если вы отправляете Unicode, то хотите, чтобы он был закодирован в UTF-8. Flask сделает за вас кодировку и установку соответствующих заголовков.

То же самое верно, если вы общаетесь с базами данных с помощью SQLAlchemy или аналогичной ORM-системы. Некоторые базы данных имеют протокол, который уже передает Unicode, а если это не так, то SQLAlchemy или другая ваша ORM должна позаботиться об этом.

Золотое правило

Поэтому эмпирическое правило: если вы не имеете дело с двоичными данными, работайте с Юникодом. Что означает работа с Юникодом в Python 2.x?

  • Пока вы используете только кодовые точки ASCII (в основном цифры, некоторые специальные символы латинских букв без умляутов и прочей фантастики), вы можете использовать обычные строковые литералы ('Hello World').

  • если вам нужно в строке что-то еще, кроме ASCII, вы должны пометить эту строку как строку Unicode, добавив к ней строчную букву u. (например, u'Hänsel und Gretel')

  • если вы используете в своих файлах Python символы, не относящиеся к Юникоду, вам необходимо указать Python, какую кодировку использует ваш файл. Опять же, для этой цели я рекомендую UTF-8. Чтобы сообщить интерпретатору вашу кодировку, вы можете поместить # -*- coding: utf-8 -*- в первую или вторую строку вашего исходного файла Python.

  • Jinja настроена на декодирование файлов шаблонов из UTF-8. Поэтому не забудьте указать своему редактору сохранять файл в формате UTF-8.

Кодирование и декодирование себя

Если вы работаете с файловой системой или чем-то, что не совсем основано на Unicode, вам придется убедиться, что вы правильно декодируете при работе с интерфейсом Unicode. Так, например, если вы хотите загрузить файл из файловой системы и вставить его в шаблон Jinja2, вам придется декодировать его из кодировки этого файла. Здесь возникает старая проблема, связанная с тем, что текстовые файлы не указывают свою кодировку. Поэтому сделайте себе одолжение и ограничьтесь UTF-8 для текстовых файлов.

В любом случае. Для загрузки такого файла с Юникодом можно использовать встроенный метод str.decode():

def read_file(filename, charset='utf-8'):
    with open(filename, 'r') as f:
        return f.read().decode(charset)

Для перехода от Юникода к определенной кодировке, например UTF-8, можно использовать метод unicode.encode():

def write_file(filename, contents, charset='utf-8'):
    with open(filename, 'w') as f:
        f.write(contents.encode(charset))

Настройка редакторов

В настоящее время большинство редакторов сохраняют текст в формате UTF-8 по умолчанию, но если ваш редактор не настроен на это, вам придется изменить его. Ниже приведены некоторые общие способы настройки редактора на сохранение в формате UTF-8:

  • Vim: поместите set enc=utf-8 в ваш файл .vimrc.

  • Emacs: либо используйте cookie кодировки, либо поместите это в ваш файл .emacs:

    (prefer-coding-system 'utf-8)
    (setq default-buffer-file-coding-system 'utf-8)
    
  • Notepad++:

    1. Перейдите в Настройки -> Предпочтения ….

    2. Выберите вкладку «Новый документ/каталог по умолчанию».

    3. Выберите «UTF-8 без BOM» в качестве кодировки

    Также рекомендуется использовать формат новой строки Unix, его можно выбрать на той же панели, но это не является обязательным условием.