UnicodeDecodeError: codec 'ascii' tidak dapat mendekode byte 0xef di posisi 1

106

Saya mengalami beberapa masalah saat mencoba mengenkode string ke UTF-8. Saya sudah mencoba banyak hal, termasuk menggunakan string.encode('utf-8')dan unicode(string), tetapi saya mendapatkan kesalahan:

UnicodeDecodeError: 'ascii' codec tidak dapat mendekode byte 0xef di posisi 1: ordinal tidak dalam jangkauan (128)

Ini string saya:

(。・ω・。)ノ

Saya tidak melihat apa yang salah, ada ide?

Sunting: Masalahnya adalah bahwa mencetak string seperti itu tidak ditampilkan dengan benar. Juga, kesalahan ini ketika saya mencoba mengubahnya:

Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-5: ordinal not in range(128)
Markum
sumber
Itu hanya string yang biasanya dimasukkan. Hal yang sama terjadi ketika saya mencoba mencetaknya.
Markum
Saya menemui hal yang sama ketika pip menginstal, dan memperbaikinya dari sini: [instal beberapa pengembangan] [1] [1]: stackoverflow.com/questions/17931726/…
BollMose

Jawaban:

70

Ini terkait dengan pengkodean terminal Anda yang tidak disetel ke UTF-8. Ini terminal saya

$ echo $LANG
en_GB.UTF-8
$ python
Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
(。・ω・。)ノ
>>> 

Di terminal saya, contohnya bekerja dengan yang di atas, tetapi jika saya menyingkirkan LANGpengaturannya maka itu tidak akan berhasil

$ unset LANG
$ python
Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-5: ordinal not in range(128)
>>> 

Lihat dokumen untuk varian linux Anda untuk mengetahui bagaimana membuat perubahan ini permanen.

Nick Craig-Wood
sumber
1
Lokal yang hilang juga bisa menjadi alasan. Untuk menginstalnya, jalankan sudo apt-get install language-pack-deatau sudo locale-gen de_DE.UTF-8(untuk bahasa Jerman).
Non
Bagi saya, variabel lingkungan yang hilang adalah LC_ALL, dan nilai paling sederhana yang akan memperbaikinya adalahC.UTF-8
Robin Winslow
24

mencoba:

string.decode('utf-8')  # or:
unicode(string, 'utf-8')

edit:

'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'.decode('utf-8')memberi u'(\uff61\uff65\u03c9\uff65\uff61)\uff89', yang benar.

jadi masalah Anda pasti ada di beberapa tempat lain, mungkin jika Anda mencoba melakukan sesuatu dengannya seandainya ada konversi implisit yang terjadi (bisa mencetak, menulis ke aliran ...)

untuk mengatakan lebih banyak, kita perlu melihat beberapa kode.

mata
sumber
Keduanya kembaliUnicodeEncodeError: 'charmap' codec can't encode characters in position 1-5: character maps to <undefined>
Markum
'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
Markum
1
Yang saya coba lakukan hanyalah mencetak string asli dalam format aslinya, tetapi saya mengerti (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë.
Markum
4
yang stringdienkodekan utf8. jika Anda mencetaknya, itu hanya mengirim byte ke aliran keluaran, dan jika terminal Anda tidak menafsirkannya sebagai utf8 Anda berakhir dengan sampah. dengan decodeAnda mengubahnya menjadi unicode, maka Anda dapat encodemengubahnya lagi menjadi pengkodean yang dipahami terminal Anda.
mata
21

+1 saya untuk komentar mata di https://stackoverflow.com/a/10561979/1346705 dan untuk demonstrasi Nick Craig-Wood. Anda telah memecahkan kode string dengan benar. Masalahnya ada pada printperintah saat ia mengubah string Unicode menjadi encoding konsol, dan konsol tidak mampu menampilkan string tersebut. Cobalah untuk menulis string ke dalam file dan lihat hasilnya menggunakan beberapa editor yang mendukung Unicode:

import codecs

s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
s1 = s.decode('utf-8')
f = codecs.open('out.txt', 'w', encoding='utf-8')
f.write(s1)
f.close()

Kemudian kamu akan lihat (。・ω・。)ノ.

pepr
sumber
10

Jika Anda bekerja pada host jarak jauh , lihat di PC lokal/etc/ssh/ssh_config Anda .

Jika file ini berisi baris:

SendEnv LANG LC_*

beri komentar dengan menambahkan #di bagian depan baris. Mungkin bisa membantu.

Dengan baris ini, sshmengirimkan variabel lingkungan terkait bahasa dari PC Anda ke host jarak jauh . Itu menyebabkan banyak masalah.

Tsutomu
sumber
Terima kasih! Ini memecahkan masalah bahwa saya memasang paket pip dengan ansible dan gelandangan
Maritza Esparza
10

Coba setel pengkodean default sistem seperti utf-8di awal skrip, sehingga semua string dikodekan menggunakan itu.

# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
Andrei Krasutski
sumber
mengapa kita perlu memuat ulang dalam kasus ini?
anjing jatuh
Ini tidak berfungsi dengan Python 3 seperti yang dijelaskan di sini . Bagi saya, jawaban Tsutomu di bawah ini berhasil.
Piyush Goel
5

Tidak masalah menggunakan kode di bawah ini di bagian atas skrip Anda seperti yang disarankan Andrei Krasutski .

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

Tetapi saya akan menyarankan Anda untuk juga menambahkan # -*- coding: utf-8 -* baris di bagian paling atas skrip.

Mengabaikannya akan menampilkan kesalahan di bawah dalam kasus saya ketika saya mencoba mengeksekusi basic.py.

$ python basic.py
  File "01_basic.py", line 14
SyntaxError: Non-ASCII character '\xd9' in file basic.py on line 14, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

Berikut ini adalah kode yang ada di basic.py yang melempar kesalahan di atas.

kode dengan kesalahan

from pylatex import Document, Section, Subsection, Command, Package
from pylatex.utils import italic, NoEscape

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def fill_document(doc):
    with doc.create(Section('ِش سثؤفهخى')):
        doc.append('إخع ساخعمي شمصشغس سحثشن فاث فقعفا')
        doc.append(italic('فشمهؤ ؤخىفثىفس شقث شمسخ ىهؤث'))

        with doc.create(Subsection('آثص ٍعلاسثؤفهخى')):
            doc.append('بشةخعس ؤقشئغ ؤاشقشؤفثقس: $&#{}')


if __name__ == '__main__':
    # Basic document
    doc = Document('basic')
    fill_document(doc)

Lalu saya menambahkan # -*- coding: utf-8 -*- baris di bagian paling atas dan dieksekusi. Berhasil.

kode tanpa kesalahan

# -*- coding: utf-8 -*-
from pylatex import Document, Section, Subsection, Command, Package
from pylatex.utils import italic, NoEscape

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def fill_document(doc):
    with doc.create(Section('ِش سثؤفهخى')):
        doc.append('إخع ساخعمي شمصشغس سحثشن فاث فقعفا')
        doc.append(italic('فشمهؤ ؤخىفثىفس شقث شمسخ ىهؤث'))

        with doc.create(Subsection('آثص ٍعلاسثؤفهخى')):
            doc.append('بشةخعس ؤقشئغ ؤاشقشؤفثقس: $&#{}')


if __name__ == '__main__':
    # Basic document
    doc = Document('basic')
    fill_document(doc)

Terima kasih.

hygull
sumber
1
Menggunakan #coding: utf-8daripada # -*- coding: utf-8 -*- ini lebih mudah diingat. Berfungsi di luar kotak dengan Python PEP 263 - Mendefinisikan Pengodean Kode Sumber Python .
Andrei Krasutski
Terima kasih untuk sarannya. Akan mencoba di akhir saya dan memperbaruinya di jawaban.
hygull
4

Tidak ada masalah dengan terminal saya. Jawaban di atas membantu saya melihat ke arah yang benar tetapi tidak berhasil sampai saya menambahkan 'ignore':

fix_encoding = lambda s: s.decode('utf8', 'ignore')

Seperti yang ditunjukkan dalam komentar di bawah, ini dapat menyebabkan hasil yang tidak diinginkan. OTOH mungkin juga melakukan trik dengan cukup baik untuk membuat semuanya bekerja dan Anda tidak peduli kehilangan beberapa karakter.

kqw
sumber
2
Ini salah, Anda memaksa fungsi lambda pengkodean Anda untuk mengabaikan pengkodean itu sendiri yang berarti Anda kehilangan karakter.
Maximiliano Rios
2
Ini memecahkan masalah saya, di mana saya tidak tahu pengkodean aslinya dan saya tidak peduli kehilangan beberapa karakter.
Edhowler
2

ini berfungsi untuk ubuntu 15.10:

sudo locale-gen "en_US.UTF-8"
sudo dpkg-reconfigure locales
wlredeye.dll
sumber
1

Sepertinya string Anda dikodekan utf-8, jadi apa sebenarnya masalahnya? Atau apa yang kamu coba lakukan disini ..?

Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
(。・ω・。)ノ
>>> s2 = u'(。・ω・。)ノ'
>>> s2 == s1
True
>>> s2
u'(\uff61\uff65\u03c9\uff65\uff61)\uff89'
wim
sumber
Mencetak string asli seperti yang diberikan (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë, saya ingin menyandikannya dengan benar.
Markum
1

Dalam kasus saya, ini disebabkan oleh file Unicode saya disimpan dengan "BOM". Untuk mengatasi ini, saya membuka file menggunakan BBEdit dan melakukan "Save as ..." memilih untuk encoding "Unicode (UTF-8)" dan bukan yang disertakan dengan "Unicode (UTF-8, with BOM) "

pengguna336828
sumber
0

Saya mendapatkan jenis kesalahan yang sama, dan saya menemukan bahwa konsol tidak mampu menampilkan string dalam bahasa lain. Oleh karena itu saya membuat perubahan kode di bawah ini untuk mengatur default_charset sebagai UTF-8.

data_head = [('\x81\xa1\x8fo\x89\xef\x82\xa2\x95\xdb\x8f\xd8\x90\xa7\x93x\x81\xcb3\x8c\x8e\x8cp\x91\xb1\x92\x86(\x81\x86\x81\xde\x81\x85)\x81\xa1\x8f\x89\x89\xf1\x88\xc8\x8aO\x81A\x82\xa8\x8b\xe0\x82\xcc\x90S\x94z\x82\xcd\x88\xea\x90\xd8\x95s\x97v\x81\xa1\x83}\x83b\x83v\x82\xcc\x82\xa8\x8e\x8e\x82\xb5\x95\xdb\x8c\xaf\x82\xc5\x8fo\x89\xef\x82\xa2\x8am\x92\xe8\x81\xa1', 'shift_jis')]
default_charset = 'UTF-8' #can also try 'ascii' or other unicode type
print ''.join([ unicode(lin[0], lin[1] or default_charset) for lin in data_head ])
Azam Khan
sumber
-1

BOM, sering kali BOM bagi saya

vi file tersebut, gunakan

:set nobomb

dan simpan. Itu hampir selalu memperbaikinya dalam kasus saya

Olly W.
sumber
-1

Saya mengalami kesalahan yang sama, dengan URL yang berisi karakter non-ascii (byte dengan nilai> 128)

url = url.decode('utf8').encode('utf-8')

Bekerja untuk saya, dengan Python 2.7, saya kira tugas ini mengubah 'sesuatu' dalam strrepresentasi internal - yaitu, memaksa decoding yang tepat dari urutan byte yang didukung urldan akhirnya menempatkan string ke dalam utf-8 str dengan semua keajaiban di tempat yang tepat. Unicode dengan Python adalah sihir hitam bagi saya. Semoga bermanfaat

Fabiano Tarlao
sumber
-2

saya memecahkan masalah itu dengan mengubah file settings.py dengan 'ENGINE': 'django.db.backends.mysql', jangan gunakan 'ENGINE': 'mysql.connector.django',

pengguna3787102
sumber
@rayryeng Bisakah Anda menjelaskan alasan pengeditan Anda? Tampaknya sepenuhnya mengubah arti dari apa yang ditulis OP, dari merekomendasikan pengaturan tertentu hingga merekomendasikan untuk tidak melakukannya.
tidak ada
@AndrewMedico - Saya minta maaf. Saya melihat bahwa posting ini sangat mirip dengan yang lain jadi saya percaya bahwa mereka sama. Saya akan kembali.
rayryeng
-2

Cukup ubah teks secara eksplisit menjadi string menggunakan str(). Bekerja untuk saya.

Supratim Samantray
sumber