Sådan retter du: "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!

Hvordan løser man det?

I nogle andre python-baserede statiske blog-apps kan kinesiske indlæg offentliggøres med succes. Som f.eks. denne app: http://github.com/vrypan/bucket3. På mit websted http://bc3.brite.biz/ kan kinesiske indlæg offentliggøres med succes.

Endlig fik jeg det:

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

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

Let me check:

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'
>>>

Ovenstående viser, at standardkodningen af python er utf8. Så fejlen er ikke mere.

Kommentarer (14)

Dette er det klassiske "unicode-problem". Jeg tror, at det ligger uden for rammerne af et StackOverflow-svar for at forklare fuldstændigt, hvad der sker.

Det er godt forklaret her.

I en meget kort opsummering har du sendt noget, der bliver fortolket som en streng af bytes til noget, der skal afkode den til Unicode-tegn, men standardcodec'en (ascii) fejler.

Den præsentation, som jeg henviste dig til, indeholder råd til at undgå dette. Gør din kode til en "unicode sandwich". I Python 2 hjælper brugen af from __future__ import unicode_literals.

Opdatering: hvordan kan koden rettes:

OK - i din variabel "source" du har nogle bytes. Det fremgår ikke klart af dit spørgsmål, hvordan de er kommet derind - måske har du læst dem fra en webformular? Under alle omstændigheder er de ikke kodet med ascii, men python forsøger at konvertere dem til unicode under antagelse af, at de er det. Du er nødt til at fortælle den eksplicit, hvad kodningen er. Det betyder, at du skal vide, hvad kodningen er! Det er ikke altid let, og det afhænger helt af, hvor strengen kommer fra. Du kan eksperimentere med nogle almindelige kodninger - f.eks. UTF-8. Du fortæller unicode() kodningen som en anden parameter:

source = unicode(source, 'utf-8')
Kommentarer (11)

I nogle tilfælde, når du kontrollerer din standardkodning (print sys.getdefaultencoding()), får du tilbage, at du bruger ASCII. Hvis du ændrer til UTF-8, virker det ikke, afhængigt af indholdet af din variabel. Jeg har fundet en anden måde:

import sys
reload(sys)  
sys.setdefaultencoding('Cp1252')
Kommentarer (4)