Строковый литерал байта с символами не-ascii
Видимо, я могу сделать это в Python 2.7:
value = '國華'
Кажется, Python использует кодировку для кодирования символов в строковом литерале в байтовую строку. Что это за кодировка? Это кодировка, определенная в sys.getdefaultencoding()
, кодировка исходного файла или что-то еще?
благодаря
- Функции ugettext и ugettext_lazy, не распознанные makemessages в Python Django
- Доступ к нетранслированному содержимому Django's ugettext_lazy
- Os.path Python задыхается от имен иврита
- Python: что означает «…» .encode («utf8»)?
- Гендерная проблема в переводе django i18n
getdefaultencoding
имеет никакого отношения к кодировке исходного файла или терминала. Это кодировка, используемая для неявного преобразования строк байтов в строки Unicode и всегда должна быть «ascii» на Python 2.X («utf8» на Python 3.X).
На Python 2.X ваша строка кода в скрипте без объявления кодировки вызывает ошибку:
SyntaxError: Non-ASCII character '\x87' in file ...
Фактический символ не ASCII может отличаться, но он не будет работать без объявления кодирования. Объявление кодирования требуется для использования символов, отличных от ASCII, на Python 2.X. Объявление кодирования должно соответствовать кодировке исходного файла. Например:
# coding: utf8 value = '國華'
при сохранении как cp936 производит:
SyntaxError: 'utf8' codec can't decode byte 0x87 in position 9: invalid start byte
Когда кодировка верна, байты в байтовой строке буквально находятся в исходном файле, поэтому они будут содержать закодированные байты символов. Когда Python анализирует строку Unicode, байты декодируются с использованием объявленной исходной кодировки в Unicode. Обратите внимание на разницу при печати строки байта UTF-8 и строки Unicode на консоли cp936:
# coding: utf8 value = '國華' print value,repr(value) value = u'國華' print value,repr(value)
Вывод:
鍦嬭彲 '\xe5\x9c\x8b\xe8\x8f\xaf'國華 u'\u570b\u83ef'
Строка байтов содержит 3-байтные кодировки UTF-8 двух символов, но отображается неправильно, поскольку последовательность байтов не понятна терминалу cp936. Юникод напечатан правильно, а строка содержит кодовые точки Юникода, декодированные из байтов UTF-8 исходного файла.
Обратите внимание на разницу при объявлении и использовании кодировки, которая соответствует терминалу:
# coding: cp936 value = '國華' print value,repr(value) value = u'國華' print value,repr(value)
Вывод:
國華 '\x87\xf8\xc8A'國華 u'\u570b\u83ef'
Содержимое строки байта теперь представляет собой 2-байтные кодировки cp936 двух символов («A», эквивалентные «\ x41») и отображается правильно, так как терминал понимает последовательность байтов cp936. Строка Unicode содержит те же кодовые точки Юникода для двух символов, что и предыдущий пример, потому что последовательность исходного байта была декодирована с использованием объявленной исходной кодировки в Unicode.
Если сценарий имеет правильное объявление кодировки источника и использует строки Unicode для текста, он отображает правильные символы 1 независимо от терминальной кодировки 2 . Он будет UnicodeEncodeError
если терминал не поддерживает символ, а не отображает неправильный символ.
Заключительное примечание: Python 2.X по умолчанию использует кодировку ascii, если не объявлено иначе, и разрешает символы без символов ASCII в байтовых строках, если их поддерживает кодировка. Python 3.X по умолчанию использует «utf8» кодировку (поэтому не забудьте сохранить в этой кодировке или объявить иначе) и не допускает символов, отличных от ASCII, в байтовых строках.
1 Если шрифт терминала поддерживает символ.
2 Если кодировка терминала поддерживает символ.
value = b'國華'
не имеет смысла ( b
подразумевается в Python 2.x) – зачем вы хотите, чтобы строка байтов содержала символы ? Python просто воспроизводит байты в любой кодировке, используемой вашим терминалом / редактором. То, что вы хотите, это строка символов :
value = u'國華'
В исходном коде файла (в отличие от интерактивной оболочки) не забудьте объявить кодировку , добавив следующую строку в начало файла:
# -*- coding: utf-8 -*-
- Поиск хорошей замены для Psyco (компилятор Python-> C)
- Как использовать python urlopen соскабливание после завершения страницы, загружая все результаты поиска?
- Возможно ли создать один файл из базы данных Sphinx?
- Как получить текущий язык в django?
- Parse French date in python
- Django i18n не работает
- Как включить тег {% trans%} для шаблонов jinja?
- CommandError: Не удается найти xgettext. с django i18n
- Использовать языковой стандарт Python или его эквивалент в веб-приложениях?
- Почему функции makemessages для локализации языка Django игнорируют html-файлы?
- В Django, как определить, доступен ли перевод для данного текста?