Hogyan javítható: "UnicodeDecodeError: 'ascii' codec can't decode byte"

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!

Hogyan javítsam meg?

Néhány más python-alapú statikus blogalkalmazásban a kínai bejegyzés sikeresen közzétehető. Ilyen például ez az alkalmazás: http://github.com/vrypan/bucket3. Az én webhelyemen http://bc3.brite.biz/, a kínai bejegyzéseket sikeresen közzé lehet tenni.

Végre megvan:

as3:/usr/local/lib/python2.7/site-packages# cat sitecustomize.py
# encoding=utf8  
import sys  

reload(sys)  
sys.setdefaultencoding('utf8')

Hadd nézzem meg:

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)

>>> sys.getdefaultencoding()
'utf8'
>>>

A fentiek szerint a python alapértelmezett kódolása utf8. Ekkor a hiba már nem jelentkezik.

Kommentárok (14)

Ez a klasszikus "unicode probléma". Úgy vélem, hogy ennek magyarázata meghaladja egy StackOverflow-válasz hatókörét, hogy teljesen elmagyarázza, mi történik.

Jól meg van magyarázva itt.

Nagyon röviden összefoglalva, átadtál valamit, amit bájtként értelmezel valaminek, aminek Unicode karakterekre kell dekódolnia, de az alapértelmezett codec (ascii) nem működik.

A bemutató, amire mutattam, tanácsokat ad ennek elkerülésére. Legyen a kódod egy "unicode szendvics". A Python 2-ben a from __future__ import unicode_literals használata segít.

Frissítés: hogyan lehet a kódot javítani:

OK - a változóban "source" van néhány bájt. A kérdésedből nem derül ki, hogyan kerültek oda - talán egy webes űrlapról olvastad be őket? Mindenesetre nem ascii kódolásúak, de a python megpróbálja őket unicode-ba konvertálni, feltételezve, hogy azok. Kifejezetten meg kell mondanod neki, hogy mi a kódolás. Ez azt jelenti, hogy tudnod kell, hogy mi a kódolás! Ez nem mindig könnyű, és teljesen attól függ, hogy honnan származik ez a karakterlánc. Kísérletezhetsz néhány gyakori kódolással - például UTF-8. Az unicode()-nak második paraméterként megadja a kódolást:

source = unicode(source, 'utf-8')
Kommentárok (11)

Bizonyos esetekben, amikor ellenőrzi az alapértelmezett kódolást (print sys.getdefaultencoding()), azt adja vissza, hogy ASCII-t használ. Ha UTF-8-ra váltasz, akkor a változó tartalmától függően nem működik. Találtam egy másik módszert:

import sys
reload(sys)  
sys.setdefaultencoding('Cp1252')
Kommentárok (4)