as3:~/ngokevin-site# nano content/blog/20140114_test-chinese.mkd
as3:~/ngokevin-site# wok
Traceback (most recent call last):
File "/usr/local/bin/wok", line 4, in
Engine()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 104, in init
self.load_pages()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 238, in load_pages
p = Page.from_file(os.path.join(root, f), self.options, self, renderer)
File "/usr/local/lib/python2.7/site-packages/wok/page.py", line 111, in from_file
page.meta['content'] = page.renderer.render(page.original)
File "/usr/local/lib/python2.7/site-packages/wok/renderers.py", line 46, in render
return markdown(plain, Markdown.plugins)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 419, in markdown
return md.convert(text)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 281, in convert
source = unicode(source)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128). -- Note: Markdown only accepts unicode input!
Как это исправить?
В некоторых других статических приложениях для блогов на Python публикация на китайском языке может быть успешно опубликована. Например, это приложение: http://github.com/vrypan/bucket3 . На моем сайте http://bc3.brite.biz/ китайская почта может быть успешно опубликована.
Ответы:
tl; dr / quick fix
reload
хакиUnicode Zen в Python 2.x - длинная версия
Не видя источника, трудно понять причину, поэтому мне придется говорить в целом.
UnicodeDecodeError: 'ascii' codec can't decode byte
Обычно это происходит, когда вы пытаетесь преобразовать Python 2.x,str
который не поддерживает ASCII, в строку Unicode без указания кодировки исходной строки.Вкратце, строки Unicode - это совершенно отдельный тип строки Python, который не содержит никакой кодировки. Они содержат только коды точек Unicode и поэтому могут содержать любую точку Unicode по всему спектру. Строки содержат кодированный текст, beit UTF-8, UTF-16, ISO-8895-1, GBK, Big5 и т. Д. Строки декодируются в Unicode, а Unicodes - в строки . Файлы и текстовые данные всегда передаются в закодированных строках.
Авторы модуля Markdown, вероятно, используют
unicode()
(там, где выбрасывается исключение) в качестве качественного шлюза для остальной части кода - он преобразует ASCII или переупорядочивает существующие строки Unicodes в новую строку Unicode. Авторы Markdown не могут знать кодировку входящей строки, поэтому будут полагаться на то, что вы декодируете строки в строки Unicode, прежде чем переходить к Markdown.Строки Unicode могут быть объявлены в вашем коде, используя
u
префикс к строкам. НапримерСтроки Unicode могут также поступать из файлов, баз данных и сетевых модулей. Когда это происходит, вам не нужно беспокоиться о кодировке.
Gotchas
Преобразование из
str
в Unicode может произойти, даже если вы не вызываете явноunicode()
.Следующие сценарии вызывают
UnicodeDecodeError
исключения:Примеры
На следующей диаграмме вы можете видеть, как слово
café
было закодировано в кодировке «UTF-8» или «Cp1252» в зависимости от типа терминала. В обоих примерахcaf
это просто обычные ascii. В UTF-8é
кодируется с использованием двух байтов. В «Cp1252» é равно 0xE9 (что также является значением точки Unicode (это не совпадение)). Вызывается правильныйdecode()
код, и преобразование в Юникод Python прошло успешно:На этой диаграмме
decode()
вызывается сascii
(что аналогично вызовуunicode()
без заданной кодировки). Поскольку ASCII не может содержать байтов больше чем0x7F
, это вызоветUnicodeDecodeError
исключение:Юникод сэндвич
Хорошей практикой является формирование сэндвича Unicode в вашем коде, где вы декодируете все входящие данные в строки Unicode, работаете с Unicodes, а затем кодируете в
str
s при выходе. Это избавит вас от беспокойства о кодировании строк в середине вашего кода.Ввод / Декодирование
Исходный код
Если вам нужно добавить не-ASCII в ваш исходный код, просто создайте строки в Юникоде, добавив к префиксу строку
u
. НапримерЧтобы позволить Python декодировать ваш исходный код, вам необходимо добавить заголовок кодирования, соответствующий фактической кодировке вашего файла. Например, если ваш файл был закодирован как «UTF-8», вы должны использовать:
Это необходимо только в том случае, если в вашем исходном коде не-ASCII .
файлы
Обычно не-ASCII данные получаются из файла.
io
Модуль обеспечивает TextWrapper , который декодирует файл на лету, используя заданныйencoding
. Вы должны использовать правильную кодировку для файла - это не может быть легко угадано. Например, для файла UTF-8:my_unicode_string
тогда будет подходящим для перехода к Markdown. ЕслиUnicodeDecodeError
изread()
строки, то вы, вероятно, использовали неправильное значение кодировки.CSV файлы
Модуль Python 2.7 CSV не поддерживает символы не ASCII 😩. Однако помощь доступна с https://pypi.python.org/pypi/backports.csv .
Используйте его как выше, но передайте ему открытый файл:
Базы данных
Большинство драйверов баз данных Python могут возвращать данные в Unicode, но обычно требуют небольшой настройки. Всегда используйте строки Unicode для запросов SQL.
MySQLВ строке подключения добавьте:
Например
PostgreSQLДобавить:
HTTP
Веб-страницы могут быть закодированы практически в любой кодировке.
Content-type
Заголовок должен содержатьcharset
поле намек на кодировании. Затем содержимое может быть декодировано вручную в соответствии с этим значением. Кроме того, Python-Requests возвращает Unicodes вresponse.text
.Вручную
Если вам нужно декодировать строки вручную, вы можете просто сделать
my_string.decode(encoding)
, гдеencoding
находится соответствующая кодировка. Python 2.x поддерживаемые кодеки приведены здесь: Стандартные кодировки . Опять же, если вы получите,UnicodeDecodeError
то, вероятно, вы ошиблись кодировкой.Мясо бутерброда
Работайте с Unicodes так же, как с обычными strs.
Вывод
стандартный вывод / печать
print
пишет через поток stdout. Python пытается настроить кодировщик на стандартный вывод, чтобы Unicodes кодировались в кодировку консоли. Например, если оболочка Linuxlocale
естьen_GB.UTF-8
, выходные данные будут закодированы вUTF-8
. В Windows вы будете ограничены 8-битной кодовой страницей.Неправильно настроенная консоль, например поврежденная локаль, может привести к неожиданным ошибкам печати.
PYTHONIOENCODING
Переменная окружения может форсировать кодирование для stdout.файлы
Так же, как ввод,
io.open
может использоваться для прозрачного преобразования Unicodes в закодированные байтовые строки.База данных
Та же конфигурация для чтения позволит писать Unicodes напрямую.
Python 3
Python 3 не более Unicode способен, чем Python 2.x, однако он немного меньше запутан в теме. Например, регулярная
str
строка теперь является строкой Юникода, а стараяstr
- теперьbytes
.Кодировка по умолчанию - UTF-8, поэтому, если вы
.decode()
используете байтовую строку без кодировки, Python 3 использует кодировку UTF-8. Это, вероятно, решает 50% проблем Unicode людей.Кроме того,
open()
по умолчанию работает в текстовом режиме, поэтому возвращает декодированныйstr
(Unicode). Кодировка получена из вашей локали, которая имеет тенденцию быть UTF-8 в системах Un * x или 8-битной кодовой страницей, такой как windows-1251, в блоках Windows.Почему вы не должны использовать
sys.setdefaultencoding('utf8')
Это неприятный хак (есть причина, которую вы должны использовать
reload
), который только маскирует проблемы и мешает переходу на Python 3.x. Разберитесь в проблеме, устраните причину и наслаждайтесь Unicode ZEN. См. Почему мы НЕ должны использовать sys.setdefaultencoding ("utf-8") в скрипте py? для дальнейших деталейисточник
io.open
для чтения / записи файлов, использоватьfrom __future__ import unicode_literals
, настраивать другие вводы / выводы данных (например, базы данных) для использования Unicode.PYTHONIOENCODING=utf-8
. Если это не помогает, вам нужно связаться с автором сценария, чтобы исправить его код.Наконец то я понял:
Дай мне проверить:
Выше показана кодировка по умолчанию для python
utf8
. Тогда ошибки больше нет.источник
str
, так что это не просрочено. В Python 2.x Unicode находился в переходном состоянии, поэтому было бы опасно предполагать кодировку при преобразовании байтов в Unicodes. Таким образом, кодировка ASCII по умолчанию в Py2 была осознанным выбором, и поэтому изменение кодировки по умолчанию требует преднамеренного взлома перезагрузкиsys
. Правильный способ устранения ошибок кодирования в Py2 - это однозначно декодировать и кодировать (байтовые) строки в Unicode, когда преобразования необходимы, а не просто предполагать, что строки кодируются в UTF-8.Это классический «вопрос Юникода». Я считаю, что объяснение этого выходит за рамки ответа StackOverflow, чтобы полностью объяснить, что происходит.
Это хорошо объяснено здесь .
В очень кратком изложении вы передали что-то, что интерпретируется как строка байтов, чему-то, что должно декодировать его в символы Unicode, но кодек по умолчанию (ascii) не работает.
В презентации, на которую я вам указал, дается совет, как этого избежать. Сделайте ваш код "бутербродом с Юникодом". В Python 2 использование
from __future__ import unicode_literals
подсказок.Обновление: как исправить код:
ОК - в вашей переменной «source» у вас есть несколько байтов. Из вашего вопроса не понятно, как они туда попали - может быть, вы читаете их из веб-формы? В любом случае они не кодируются с помощью ascii, но python пытается преобразовать их в Unicode, предполагая, что они есть. Вы должны явно сказать ему, что такое кодировка. Это означает, что вам нужно знать, что такое кодировка! Это не всегда легко, и это полностью зависит от того, откуда взялась эта строка. Вы можете поэкспериментировать с некоторыми распространенными кодировками - например, UTF-8. Вы указываете unicode () кодировку как второй параметр:
источник
currentFile = open(filename, 'rt', encoding='latin1')
илиcurrentFile = open(filename, 'rt', encoding='utf-8')
- см. здесь: stackoverflow.com/a/23917799/2047442В некоторых случаях, когда вы проверяете кодировку по умолчанию (
print sys.getdefaultencoding()
), возвращается, что вы используете ASCII. Если вы переключитесь на UTF-8, он не будет работать, в зависимости от содержимого вашей переменной. Я нашел другой способ:источник
reload(sys)
используется по этой конкретной причине.Я искал, чтобы решить следующее сообщение об ошибке:
Я наконец исправил это, указав кодировку:
Хотелось бы, чтобы это тебе тоже помогло.
источник
Причина этой ошибки: input_string должен быть Unicode, но был указан str
Причина этой ошибки: попытка конвертировать unicode input_string в unicode
Итак, сначала проверьте, что ваша input_string является
str
и преобразовать в Unicode, если необходимо:Во-вторых, вышеприведенное просто меняет тип, но не удаляет символы не ascii. Если вы хотите удалить не-ascii символы:
источник
Я считаю, что лучше всего всегда преобразовывать в Unicode, но этого трудно достичь, потому что на практике вам придется проверять и преобразовывать каждый аргумент для каждой функции и метода, которые вы когда-либо пишете, включая некоторую форму обработки строк.
Таким образом, я придумал следующий подход, чтобы гарантировать либо юникод, либо байтовые строки из любого ввода. Вкратце, включите и используйте следующие лямбды:
Примеры:
Вот еще несколько рассуждений по этому поводу .
источник
print unicode(u'Zürich', encoding="UTF-8")
а затем жалуются: «Но удивительно, что вы не можете кодировать Unicode Ext в UTF8».unicode()
не кодирует; он декодирует, и вы не можете декодировать Unicode - он уже декодирован!Чтобы решить эту проблему на уровне операционной системы в установке Ubuntu, проверьте следующее:
Если вы получаете
вместо
затем установить
LC_CTYPE
иLC_ALL
вот так:источник
Encode преобразует объект Unicode в строковый объект. Я думаю, что вы пытаетесь закодировать строковый объект. сначала преобразуйте ваш результат в объект Unicode, а затем закодируйте этот объект Unicode в UTF-8. например
источник
У меня была та же проблема, но она не работала для Python 3. Я последовал этому, и это решило мою проблему:
Вы должны установить кодировку при чтении / записи файла.
источник
Получил ту же ошибку, и это решило мою ошибку. Спасибо! Python 2 и Python 3, отличающиеся обработкой Unicode, делают маринованные файлы совершенно несовместимыми для загрузки. Так что используйте аргумент кодирования Python pickle. Ссылка ниже помогла мне решить аналогичную проблему, когда я пытался открыть маринованные данные из моего Python 3.7, в то время как мой файл был изначально сохранен в версии Python 2.x. https://blog.modest-destiny.com/posts/python-2-and-3-compatible-pickle-save-and-load/ Я копирую функцию load_pickle в своем скрипте и вызываю load_pickle (pickle_file) во время загрузки моего input_data, как это:
Функция load_pickle находится здесь:
источник
load_pickle
функции лучше включить в ваш ответ.Это сработало для меня:
источник
Короче говоря, чтобы обеспечить правильную обработку Юникода в Python 2:
io.open
для чтения / записи файловfrom __future__ import unicode_literals
print(text.encode('ascii', 'replace').decode())
Для объяснения см. Подробный ответ @Alastair McCormack .
источник
io.open(path, 'r', encoding='utf-8')
для чтения файлов в кодировке utf-8.У меня была та же ошибка, с URL-адресами, содержащими символы не ascii (байты со значениями> 128), мое решение:
Примечание: utf-8, utf8 - это просто псевдонимы. Использование только utf8 или utf-8 должно работать точно так же
В моем случае, работавшем для меня, в Python 2.7, я предполагаю, что это назначение изменило «что-то» во
str
внутреннем представлении - то есть оно вызывает правильное декодирование последовательности байтов с резервной копиейurl
и, наконец, помещает строку в utf-8str
с вся магия в нужном месте. Unicode в Python для меня черная магия. Надеюсь, полезноисточник
У меня возникла та же проблема со строкой «PastelerÃa Mallorca», и я решил:
источник
В проекте Django (1.9.10) / Python 2.7.5 у меня есть частые
`UnicodeDecodeError
исключения; главным образом, когда я пытаюсь передать строки юникода в логирование. Я сделал вспомогательную функцию для произвольных объектов, чтобы в основном форматировать в 8-битные строки ascii и заменять любые символы, отсутствующие в таблице, на «?». Я думаю, что это не лучшее решение, но так как кодировкой по умолчанию является ascii (и я не хочу ее менять), она подойдет:источник
Эта ошибка возникает, когда в нашей строке есть символы, не входящие в ASCII, и мы выполняем любые операции с этой строкой без надлежащего декодирования. Это помогло мне решить мою проблему. Я читаю файл CSV с идентификатором столбцов, текстом и расшифровкой символов, как показано ниже:
источник
Вот мое решение, просто добавьте кодировку.
with open(file, encoding='utf8') as f
А поскольку чтение файла перчаток займет много времени, я рекомендую перчатку перетянуть в файл с непостоянством. Когда в течение netx вы прочитаете веса встраивания, это сэкономит ваше время.
Ссылка Gist: https://gist.github.com/BrambleXu/634a844cdd3cd04bb2e3ba3c83aef227
источник
Укажите: # encoding = utf-8 в верхней части вашего файла Python, это должно решить проблему
источник