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/, η κινεζική ανάρτηση μπορεί να δημοσιευτεί με επιτυχία.
Τελικά το κατάλαβα:
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 για να εξηγήσει πλήρως τι συμβαίνει.
Εξηγείται καλά εδώ.
Σε πολύ σύντομη περίληψη, έχετε περάσει κάτι που ερμηνεύεται ως συμβολοσειρά bytes σε κάτι που πρέπει να το αποκωδικοποιήσει σε χαρακτήρες Unicode, αλλά ο προεπιλεγμένος κωδικοποιητής (ascii) αποτυγχάνει.
Η παρουσίαση στην οποία σας παρέπεμψα παρέχει συμβουλές για την αποφυγή αυτού του προβλήματος. Κάντε τον κώδικά σας ένα σάντουιτς "unicode sandwich". Στην Python 2, η χρήση της from __future__ import unicode_literals
βοηθάει.
Ενημέρωση: πώς μπορεί να διορθωθεί ο κώδικας:
Εντάξει - στη μεταβλητή σας "source" έχετε μερικά bytes. Δεν είναι σαφές από την ερώτησή σας πώς μπήκαν εκεί - ίσως τα διαβάσατε από μια φόρμα ιστού; Σε κάθε περίπτωση, δεν είναι κωδικοποιημένα με ascii, αλλά η python προσπαθεί να τα μετατρέψει σε unicode υποθέτοντας ότι είναι. Πρέπει να της πείτε ρητά ποια είναι η κωδικοποίηση. Αυτό σημαίνει ότι πρέπει να γνωρίζετε ποια είναι η κωδικοποίηση! Αυτό δεν είναι πάντα εύκολο, και εξαρτάται αποκλειστικά από το από πού προήλθε αυτό το αλφαριθμητικό. Θα μπορούσατε να πειραματιστείτε με κάποιες κοινές κωδικοποιήσεις - για παράδειγμα UTF-8. Λέτε στην unicode() την κωδικοποίηση ως δεύτερη παράμετρο:
source = unicode(source, 'utf-8')
Σε ορισμένες περιπτώσεις, όταν ελέγχετε την προεπιλεγμένη κωδικοποίηση (print sys.getdefaultencoding()
), επιστρέφει ότι χρησιμοποιείτε ASCII. Αν αλλάξετε σε UTF-8, δεν λειτουργεί, ανάλογα με το περιεχόμενο της μεταβλητής σας.
Βρήκα έναν άλλο τρόπο:
import sys
reload(sys)
sys.setdefaultencoding('Cp1252')