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!
Как да го поправя?
В някои други приложения за статични блогове, базирани на питон, китайският пост може да бъде публикуван успешно. Като например това приложение: http://github.com/vrypan/bucket3. В моя сайт http://bc3.brite.biz/ китайският пост може да бъде публикуван успешно.
Накрая го получих:
as3:/usr/local/lib/python2.7/site-packages# cat sitecustomize.py
# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
Нека проверя:
as3:~/ngokevin-site# python
Python 2.7.6 (default, Dec 6 2013, 14:49:02)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.getdefaultencoding()
'utf8'
>>>
Горното показва, че кодирането по подразбиране на Python е utf8
. Тогава грешката вече не се появява.
Това е класически "проблем с Unicode". Смятам, че обяснението на този проблем е извън обхвата на отговора в StackOverflow, за да обясни напълно какво се случва.
Това е добре обяснено тук.
Накратко, предали сте нещо, което се интерпретира като низ от байтове, на нещо, което трябва да го декодира в Unicode символи, но кодекът по подразбиране (ascii) не успява.
Презентацията, към която ви насочих, съдържа съвети за избягване на това. Направете кода си "сандвич с Unicode". В Python 2 помага използването на from __future__ import unicode_literals
.
Актуализация: как може да се поправи кодът:
Добре - в променливата "source" имате няколко байта. От въпроса ви не става ясно как са попаднали там - може би сте ги прочели от уеб форма? Във всеки случай те не са кодирани с ascii, но python се опитва да ги преобразува в unicode, приемайки, че са. Трябва изрично да му кажете какво е кодирането. Това означава, че трябва да знаете какво е кодирането! Това невинаги е лесно и зависи изцяло от това, откъде е дошъл този низ. Можете да експериментирате с някои често срещани кодировки - например UTF-8. Посочвате кодировката на unicode() като втори параметър:
source = unicode(source, 'utf-8')
В някои случаи, когато проверявате кодирането по подразбиране (print sys.getdefaultencoding()
), се връща, че използвате ASCII. Ако промените на UTF-8, това не'работи, в зависимост от съдържанието на променливата ви.
Намерих друг начин:
import sys
reload(sys)
sys.setdefaultencoding('Cp1252')