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!
Bagaimana memperbaikinya?
Di beberapa aplikasi blog statis berbasis python lainnya, pos Cina dapat dipublikasikan dengan sukses. Seperti aplikasi ini: http://github.com/vrypan/bucket3 . Di situs saya http://bc3.brite.biz/ , tulisan berbahasa Mandarin dapat dipublikasikan dengan sukses.
python
python-2.7
chinese-locale
nelayan
sumber
sumber
Jawaban:
tl; dr / perbaikan cepat
reload
peretasan cepatUnicode Zen dengan Python 2.x - Versi Panjang
Tanpa melihat sumbernya, sulit untuk mengetahui akar masalahnya, jadi saya harus berbicara secara umum.
UnicodeDecodeError: 'ascii' codec can't decode byte
umumnya terjadi ketika Anda mencoba untuk mengubah Python 2.xstr
yang berisi non-ASCII ke string Unicode tanpa menentukan pengkodean dari string asli.Singkatnya, string Unicode adalah tipe string Python yang sepenuhnya terpisah yang tidak mengandung pengodean apa pun. Mereka hanya memegang kode titik Unicode dan karena itu dapat menampung titik Unicode dari seluruh spektrum. String berisi teks yang disandikan, beit UTF-8, UTF-16, ISO-8895-1, GBK, Big5 dll. String di-decode ke Unicode dan Unicode di -encode ke string . File dan data teks selalu ditransfer dalam string yang disandikan.
Penulis modul Markdown mungkin menggunakan
unicode()
(di mana pengecualian dilemparkan) sebagai gerbang kualitas ke sisa kode - itu akan mengkonversi ASCII atau membungkus kembali string Unicodes yang ada ke string Unicode baru. Penulis penurunan harga tidak dapat mengetahui pengkodean string yang masuk sehingga akan bergantung pada Anda untuk mendekode string ke string Unicode sebelum melewati Markdown.String Unicode dapat dideklarasikan dalam kode Anda menggunakan
u
awalan ke string. MisalnyaString Unicode juga dapat berasal dari file, database, dan modul jaringan. Ketika ini terjadi, Anda tidak perlu khawatir tentang pengkodean.
Gotcha
Konversi dari
str
ke Unicode dapat terjadi bahkan ketika Anda tidak secara eksplisit meneleponunicode()
.Skenario berikut menyebabkan
UnicodeDecodeError
pengecualian:Contohnya
Dalam diagram berikut, Anda dapat melihat bagaimana kata
café
tersebut dikodekan dalam pengkodean "UTF-8" atau "Cp1252" tergantung pada jenis terminal. Dalam kedua contoh,caf
hanya ascii biasa. Dalam UTF-8,é
dikodekan menggunakan dua byte. Dalam "Cp1252", é adalah 0xE9 (yang juga merupakan nilai titik Unicode (bukan kebetulan)). Yang benardecode()
dipanggil dan konversi ke Python Unicode berhasil:Dalam diagram ini,
decode()
dipanggil denganascii
(yang sama dengan memanggilunicode()
tanpa diberikan pengkodean). Karena ASCII tidak dapat memuat byte lebih dari0x7F
, ini akan menghasilkanUnicodeDecodeError
pengecualian:Sandwich Unicode
Ini praktik yang baik untuk membentuk sandwich Unicode dalam kode Anda, tempat Anda mendekode semua data yang masuk ke string Unicode, bekerja dengan Unicode, lalu menyandikan ke
str
saat keluar. Ini menyelamatkan Anda dari khawatir tentang pengkodean string di tengah kode Anda.Input / Dekode
Kode sumber
Jika Anda perlu memanggang non-ASCII ke dalam kode sumber Anda, cukup buat string Unicode dengan awalan string dengan a
u
. MisalnyaUntuk mengizinkan Python mendekode kode sumber Anda, Anda perlu menambahkan header pengodean untuk cocok dengan pengodean sebenarnya dari file Anda. Misalnya, jika file Anda dikodekan sebagai 'UTF-8', Anda akan menggunakan:
Ini hanya diperlukan ketika Anda memiliki non-ASCII dalam kode sumber Anda .
File
Biasanya data non-ASCII diterima dari file. The
io
modul menyediakan TextWrapper yang menerjemahkan file Anda dengan cepat, menggunakan diberiencoding
. Anda harus menggunakan penyandian yang benar untuk file - tidak dapat dengan mudah ditebak. Misalnya, untuk file UTF-8:my_unicode_string
maka akan cocok untuk diteruskan ke Penurunan harga. Jika aUnicodeDecodeError
dariread()
baris, maka Anda mungkin menggunakan nilai penyandian yang salah.File CSV
Modul Python 2.7 CSV tidak mendukung karakter non-ASCII 😩. Namun, bantuan ada di tangan, dengan https://pypi.python.org/pypi/backports.csv .
Gunakan seperti di atas tetapi berikan file yang dibuka itu:
Basis data
Sebagian besar driver database Python dapat mengembalikan data dalam Unicode, tetapi biasanya memerlukan sedikit konfigurasi. Selalu gunakan string Unicode untuk kueri SQL.
MySQLDalam string koneksi tambahkan:
Misalnya
PostgreSQLMenambahkan:
HTTP
Halaman web dapat dikodekan dalam hampir semua pengkodean. The
Content-type
header harus berisicharset
lapangan untuk mengisyaratkan pengkodean. Konten kemudian dapat diterjemahkan secara manual terhadap nilai ini. Atau, Python-Requests mengembalikan Unicodesresponse.text
.Secara manual
Jika Anda harus mendekode string secara manual, Anda bisa melakukannya
my_string.decode(encoding)
, di manaencoding
pengkodean yang sesuai. Python 2.x codec yang didukung diberikan di sini: Penyandian Standar . Sekali lagi, jika Anda mendapatkannyaUnicodeDecodeError
maka Anda mungkin mendapatkan pengkodean yang salah.Daging sandwich
Bekerja dengan Unicodes seperti yang biasa Anda lakukan strs.
Keluaran
stdout / pencetakan
print
menulis melalui aliran stdout. Python mencoba mengonfigurasi enkoder pada stdout sehingga Unicodes dikodekan ke enkode konsol. Misalnya, jika shell Linuxlocale
adalahen_GB.UTF-8
, output akan dikodekan keUTF-8
. Di Windows, Anda akan dibatasi untuk halaman kode 8bit.Konsol yang dikonfigurasi secara tidak benar, seperti lokal yang korup, dapat menyebabkan kesalahan cetak yang tidak terduga.
PYTHONIOENCODING
variabel lingkungan dapat memaksa pengodean untuk stdout.File
Sama seperti input,
io.open
dapat digunakan untuk secara transparan mengkonversi Unicodes ke string byte yang dikodekan.Basis data
Konfigurasi yang sama untuk membaca akan memungkinkan Unicodes ditulis secara langsung.
Python 3
Python 3 tidak lebih Unicode mampu daripada Python 2.x, namun sedikit kurang bingung pada topik. Misalnya biasa
str
sekarang menjadi string Unicode dan yang lamastr
sekarangbytes
.Pengkodean default adalah UTF-8, jadi jika Anda
.decode()
byte string tanpa memberikan pengkodean, Python 3 menggunakan pengkodean UTF-8. Ini mungkin memperbaiki 50% masalah Unicode orang.Selanjutnya,
open()
beroperasi dalam mode teks secara default, sehingga mengembalikan diterjemahkanstr
(Unicode). Pengkodean berasal dari lokal Anda, yang cenderung UTF-8 pada sistem Un * x atau halaman kode 8-bit, seperti windows-1251, pada kotak Windows.Mengapa Anda tidak harus menggunakannya
sys.setdefaultencoding('utf8')
Ini adalah hack jahat (ada alasan Anda harus menggunakan
reload
) yang hanya akan menutupi masalah dan menghambat migrasi Anda ke Python 3.x. Pahami masalahnya, perbaiki akar penyebabnya dan nikmati Unicode zen. Lihat Mengapa kita TIDAK menggunakan sys.setdefaultencoding ("utf-8") dalam skrip py? untuk keterangan lebih lanjutsumber
io.open
untuk membaca / menulis file, gunakanfrom __future__ import unicode_literals
, konfigurasikan input / output data lainnya (misalnya, basis data) untuk menggunakan unicode.PYTHONIOENCODING=utf-8
. Jika itu tidak memperbaikinya, Anda harus menghubungi penulis skrip untuk memperbaiki kode mereka.Akhirnya saya mendapatkannya:
Biarkan saya periksa:
Di atas menunjukkan pengkodean default python adalah
utf8
. Maka kesalahan tidak ada lagi.sumber
str
, sehingga tidak terlambat di sana. Dalam Python 2.x, Unicode berada dalam keadaan transisi, jadi akan berbahaya untuk menganggap pengodean ketika mengkonversi byte ke Unicodes. Oleh karena itu, penyandian standar ASCII dari Py2 adalah pilihan yang disengaja dan mengapa mengubah penyandian default memerlukan retasan yang disengaja untuk memuat ulangsys
. Cara yang benar untuk menghalau kesalahan penyandian dalam Py2 adalah dengan mendekodekan string dan penyandian (byte) yang jelas ke Unicode, ketika konversi diperlukan - bukan hanya menganggap string disandikan UTF-8.Ini adalah "masalah unicode" klasik. Saya percaya bahwa menjelaskan ini di luar cakupan jawaban StackOverflow untuk sepenuhnya menjelaskan apa yang terjadi.
Dijelaskan dengan baik di sini .
Dalam ringkasan yang sangat singkat, Anda telah mengirimkan sesuatu yang sedang ditafsirkan sebagai string byte ke sesuatu yang perlu diterjemahkan ke dalam karakter Unicode, tetapi codec default (ascii) gagal.
Presentasi yang saya tunjukkan kepada Anda untuk memberikan saran untuk menghindari hal ini. Jadikan kode Anda "sandwich unicode". Dalam Python 2, penggunaan
from __future__ import unicode_literals
bantuan.Pembaruan: bagaimana kode diperbaiki:
OK - dalam "sumber" variabel Anda, Anda memiliki beberapa byte. Tidak jelas dari pertanyaan Anda bagaimana mereka masuk ke sana - mungkin Anda membacanya dari formulir web? Bagaimanapun, mereka tidak dikodekan dengan ascii, tetapi python sedang mencoba untuk mengubahnya menjadi unicode dengan asumsi mereka. Anda harus secara eksplisit mengatakan apa itu pengkodean. Ini artinya Anda perlu tahu apa itu encoding! Itu tidak selalu mudah, dan itu tergantung sepenuhnya pada dari mana string ini berasal. Anda dapat bereksperimen dengan beberapa penyandian umum - misalnya UTF-8. Anda memberi tahu unicode () pengkodean sebagai parameter kedua:
sumber
currentFile = open(filename, 'rt', encoding='latin1')
ataucurrentFile = open(filename, 'rt', encoding='utf-8')
- lihat di sini: stackoverflow.com/a/23917799/2047442Dalam beberapa kasus, ketika Anda memeriksa penyandian default Anda (
print sys.getdefaultencoding()
), itu mengembalikan bahwa Anda menggunakan ASCII. Jika Anda mengubah ke UTF-8, itu tidak berfungsi, tergantung pada konten variabel Anda. Saya menemukan cara lain:sumber
reload(sys)
digunakan untuk alasan tertentu.Saya sedang mencari untuk menyelesaikan pesan kesalahan berikut:
Saya akhirnya memperbaikinya dengan menentukan 'encoding':
Semoga itu bisa membantu Anda juga.
sumber
Penyebab kesalahan ini: input_string harus unicode tetapi str diberikan
Penyebab kesalahan ini: mencoba mengubah unicode input_string menjadi unicode
Jadi pertama-tama periksa apakah input_string Anda
str
dan konversi ke unicode jika perlu:Kedua, di atas hanya mengubah jenis tetapi tidak menghapus karakter non ascii. Jika Anda ingin menghapus karakter non-ascii:
sumber
Saya menemukan yang terbaik adalah untuk selalu mengkonversi ke unicode - tetapi ini sulit dicapai karena dalam praktiknya Anda harus memeriksa dan mengkonversi setiap argumen untuk setiap fungsi dan metode yang pernah Anda tulis yang mencakup beberapa bentuk pemrosesan string.
Jadi saya datang dengan pendekatan berikut untuk menjamin string unicodes atau byte, dari salah satu input. Singkatnya, masukkan dan gunakan lambdas berikut:
Contoh:
Inilah beberapa alasan lain tentang ini .
sumber
print unicode(u'Zürich', encoding="UTF-8")
dan kemudian mengeluh "Tapi luar biasa Anda tidak dapat menyandikan unicode ext ke UTF8".unicode()
tidak menyandikan; itu diterjemahkan dan Anda tidak dapat men-decode Unicode - sudah diterjemahkan!Untuk menyelesaikan ini pada tingkat sistem operasi dalam instalasi Ubuntu, periksa hal-hal berikut:
Jika Anda mendapatkan
dari pada
kemudian atur
LC_CTYPE
danLC_ALL
sukai ini:sumber
Encode mengkonversi objek unicode ke objek string. Saya pikir Anda mencoba untuk menyandikan objek string. pertama-tama ubah hasil Anda menjadi objek unicode dan kemudian enkode objek unicode menjadi 'utf-8'. sebagai contoh
sumber
Saya memiliki masalah yang sama tetapi tidak berhasil untuk Python 3. Saya mengikuti ini dan itu memecahkan masalah saya:
Anda harus mengatur penyandian saat Anda membaca / menulis file.
sumber
Mendapat kesalahan yang sama dan ini menyelesaikan kesalahan saya. Terima kasih! python 2 dan python 3 berbeda dalam penanganan unicode membuat file acar sangat tidak kompatibel untuk memuat. Jadi Gunakan argumen encoding python acar. Tautan di bawah ini membantu saya memecahkan masalah yang sama ketika saya mencoba untuk membuka data acar dari python 3.7 saya, sementara file saya awalnya disimpan dalam versi python 2.x. https://blog.modest-destiny.com/posts/python-2-and-3-compatible-pickle-save-and-load/ Saya menyalin fungsi load_pickle dalam skrip saya dan memanggil load_pickle (pickle_file) saat memuat saya input_data seperti ini:
Fungsi load_pickle ada di sini:
sumber
load_pickle
fungsi dalam jawaban Anda.Ini bekerja untuk saya:
sumber
Singkatnya, untuk memastikan penanganan unicode yang benar di Python 2:
io.open
untuk membaca / menulis filefrom __future__ import unicode_literals
print(text.encode('ascii', 'replace').decode())
Untuk penjelasan, lihat jawaban terinci @Alastair McCormack .
sumber
io.open(path, 'r', encoding='utf-8')
untuk membaca file yang dikodekan utf-8.Saya mengalami kesalahan yang sama, dengan URL yang berisi karakter non-ascii (byte dengan nilai> 128), solusi saya:
Catatan: utf-8, utf8 hanyalah alias. Hanya menggunakan 'utf8' atau 'utf-8' harus bekerja dengan cara yang sama
Dalam kasus saya, bekerja untuk saya, dalam Python 2.7, saya kira tugas ini mengubah 'sesuatu' dalam
str
representasi internal - yaitu, memaksa decoding yang tepat dari urutan byte yang didukungurl
dan akhirnya menempatkan string ke utf-8str
dengan semua keajaiban di tempat yang tepat. Unicode dalam Python adalah ilmu hitam bagi saya. Semoga bermanfaatsumber
Saya mendapat masalah yang sama dengan string "PastelerÃa Mallorca" dan saya memecahkannya dengan:
sumber
Dalam proyek Django (1.9.10) / Python 2.7.5 saya sering
`UnicodeDecodeError
perkecualian; terutama ketika saya mencoba memberi makan string unicode untuk logging. Saya membuat fungsi pembantu untuk objek yang berubah-ubah pada dasarnya memformat string 8-bit ascii dan mengganti karakter yang tidak ada dalam tabel menjadi '?'. Saya pikir itu bukan solusi terbaik tetapi karena penyandian default adalah ascii (dan saya tidak ingin mengubahnya) ia akan melakukan:sumber
Kesalahan ini terjadi ketika ada beberapa karakter non ASCII di string kami dan kami melakukan operasi apa pun pada string itu tanpa decoding yang tepat. Ini membantu saya memecahkan masalah saya. Saya membaca file CSV dengan kolom ID, Teks dan karakter decoding di dalamnya seperti di bawah ini:
sumber
Ini solusi saya, tambahkan saja encoding.
with open(file, encoding='utf8') as f
Dan karena membaca file glove akan memakan waktu lama, saya merekomendasikan file glove ke file numpy. Saat netx Anda membaca bobot embedding, itu akan menghemat waktu Anda.
Tautan intisari: https://gist.github.com/BrambleXu/634a844cdd3cd04bb2e3ba3c83aef227
sumber
Tentukan: # encoding = utf-8 di bagian atas File Python Anda, itu harus memperbaiki masalah
sumber