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!
Jak to naprawić?
W niektórych innych statycznych aplikacjach blogowych opartych na Pythonie, chiński post może zostać pomyślnie opublikowany. Takich jak ta aplikacja: http://github.com/vrypan/bucket3. W mojej witrynie http://bc3.brite.biz/, chiński post może być publikowany z powodzeniem.
W końcu to mam:
as3:/usr/local/lib/python2.7/site-packages# cat sitecustomize.py
# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
Pozwól mi sprawdzić:
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'
>>>
Powyższe pokazuje, że domyślnym kodowaniem pythona jest utf8
. Wtedy błąd już nie występuje.
Jest to klasyczny "problem z unicode". Wierzę, że wyjaśnienie tego wykracza poza zakres odpowiedzi StackOverflow, aby całkowicie wyjaśnić, co się dzieje.
Jest to dobrze wyjaśnione tutaj.
W bardzo krótkim podsumowaniu, przekazałeś coś, co jest interpretowane jako ciąg bajtów do czegoś, co musi zdekodować go na znaki Unicode, ale domyślny kodek (ascii) zawodzi.
Prezentacja, do której Cię skierowałem, zawiera porady, jak tego uniknąć. Uczyń swój kod "kanapką z unicode". W Pythonie 2 pomaga w tym użycie from __future__ import unicode_literals
.
Aktualizacja: jak można naprawić ten kod:
OK - w swojej zmiennej "source" masz jakieś bajty. Z Twojego pytania nie wynika jasno, jak się tam znalazły - może odczytałeś je z formularza internetowego? W każdym razie nie są one zakodowane w ascii, ale python próbuje przekonwertować je na unicode, zakładając, że są. Musisz jawnie powiedzieć mu, jakie jest kodowanie. Oznacza to, że musisz wiedzieć jakie jest kodowanie! Nie zawsze jest to łatwe, a zależy to całkowicie od tego, skąd pochodzi ten ciąg znaków. Możesz poeksperymentować z niektórymi popularnymi kodowaniami - na przykład UTF-8. Podajesz unicode() kodowanie jako drugi parametr:
source = unicode(source, 'utf-8')
W niektórych przypadkach, gdy sprawdzasz swoje domyślne kodowanie (print sys.getdefaultencoding()
), zwraca ono, że używasz ASCII. Jeśli zmienisz na UTF-8, to nie'działa, w zależności od zawartości twojej zmiennej.
Znalazłem inny sposób:
import sys
reload(sys)
sys.setdefaultencoding('Cp1252')