UnicodeDecodeError: 'ascii' codec bileşeni, konum 1'deki bayt 0xef kodunu çözemiyor


106

Bir dizeyi UTF-8 olarak kodlamaya çalışırken birkaç sorun yaşıyorum. Kullandığım dahil çok sayıda şeyleri, denedim string.encode('utf-8')ve unicode(string)ama hata alıyorum:

UnicodeDecodeError: 'ascii' codec bileşeni, 1 konumundaki bayt 0xef kodunu çözemiyor: ordinal aralıkta değil (128)

Bu benim dizim:

(。・ω・。)ノ

Neyin yanlış gittiğini anlamıyorum, herhangi bir fikriniz var mı?

Düzenleme: Sorun, dizeyi olduğu gibi yazdırmanın düzgün gösterilmemesidir. Ayrıca, dönüştürmeye çalıştığımda bu hata:

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)

Normalde eklenen bir dizedir. Aynı şey sadece yazdırmayı denediğimde de oluyor.
Markum

Pip kurulumunda aynı şeyi karşılıyorum ve buradan
düzeltiyorum

Yanıtlar:


70

Bu, terminalinizin kodlamasının UTF-8 olarak ayarlanmaması ile ilgilidir. İşte benim terminalim

$ 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
(。・ω・。)ノ
>>> 

Terminalimde örnek yukarıdakiyle çalışır, ancak LANGayardan kurtulursam işe yaramaz

$ 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)
>>> 

Bu değişikliği nasıl kalıcı hale getireceğinizi keşfetmek için linux varyantınızın belgelerine bakın.


1
Eksik yerel ayarlar da bir sebep olabilir. Bunları yüklemek için sudo apt-get install language-pack-deveya sudo locale-gen de_DE.UTF-8(almanca yerel ayarlar için) çalıştırın .
Sigara

Benim için eksik ortam değişkeni LC_ALLve onu düzeltecek en basit değer şuC.UTF-8
Robin Winslow

24

Deneyin:

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

Düzenle:

'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'.decode('utf-8')u'(\uff61\uff65\u03c9\uff65\uff61)\uff89'doğru olan verir .

yani probleminiz başka bir yerde olmalı, muhtemelen onunla bir şey yapmaya çalışırsanız, örtük bir dönüşüm devam ediyordu (yazdırmak, bir akışa yazmak olabilir ...)

daha fazlasını söylemek için biraz kod görmemiz gerekecek.


Her ikisi de dönüşUnicodeEncodeError: '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
Tek yapmaya çalıştığım orijinal dizeyi orijinal biçiminde yazdırmak, ama anlıyorum (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë.
Markum

4
stringUTF-8-kodlanmış. yazdırırsanız, yalnızca baytları çıkış akışına aktarır ve eğer terminaliniz bunu utf8 olarak yorumlamazsa, çöp ile sonuçlanırsınız. ile decodeEğer unicode dönüştürmek, sonra da olabilir encodetekrar bir kodlama terminal anlar için.
mata

21

Benim +1 mata'nın https://stackoverflow.com/a/10561979/1346705 adresindeki yorumuna ve Nick Craig-Wood'un gösterisine. Dizenin kodunu doğru bir şekilde çözdünüz. Sorun, printUnicode dizesini konsol kodlamasına dönüştüren komutla ilgilidir ve konsol dizeyi görüntüleyemez. Dizeyi bir dosyaya yazmaya çalışın ve Unicode'u destekleyen iyi bir düzenleyici kullanarak sonuca bakın:

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()

O zaman göreceksin (。・ω・。)ノ.


10

Eğer bir çalışıyorsanız uzak konak bakmak /etc/ssh/ssh_configiçin üzerine lokal PC.

Bu dosya bir satır içerdiğinde:

SendEnv LANG LC_*

#satır başına ekleyerek yorum yapın . O yardımcı olabilir.

Bu satırla, sshbilgisayarınızın dil ile ilgili ortam değişkenlerini uzaktaki ana bilgisayara gönderir . Çok fazla soruna neden olur .


Teşekkürler! Bunlar yanıtlanabilir ve serseri pip paketleri yüklemem sorununu çözdü
Maritza Esparza


5

Andrei Krasutski'nin önerdiği gibi, senaryonuzun üst kısmında aşağıdaki kodu kullanmanız sorun değil .

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

Ama # -*- coding: utf-8 -*senaryonun en üstüne de satır eklemenizi tavsiye edeceğim .

Atlamak, yürütmeye çalıştığımda benim durumumda aşağıdaki hatayı atıyor 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

Aşağıdaki, basic.pyyukarıdaki hatayı atan mevcut koddur .

hatalı kod

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)

Sonra # -*- coding: utf-8 -*-en üstüne satır ekledim ve çalıştırdım. İşe yaradı.

hatasız kod

# -*- 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)

Teşekkürler.


1
Bunun #coding: utf-8yerine kullanmak # -*- coding: utf-8 -*- hatırlamak daha kolaydır. Python PEP 263 - Python Kaynak Kodu Kodlamalarını Tanımlama ile kutudan çıkar çıkmaz çalışır .
Andrei Krasutski

Önerin için teşekkürler. Sonunda deneyecek ve cevapta güncelleyeceğim.
hygull

4

Terminalimle sorun yok. Yukarıdaki cevaplar doğru yönlere bakmama yardımcı oldu, ancak şunu ekleyene kadar benim için işe yaramadı 'ignore':

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

Aşağıdaki yorumda belirtildiği gibi, bu istenmeyen sonuçlara yol açabilir. OTOH, aynı zamanda işlerin yürümesini sağlayacak kadar iyi bir iş çıkarabilir ve bazı karakterleri kaybetmeyi umursamıyorsunuz.


2
Bu yanlış, kodlama lambda işlevinizi kodlamanın kendisini yok saymaya zorluyorsunuz, bu da karakterleri kaybediyorsunuz demektir.
Maximiliano Rios

2
Bu, orijinal kodlamayı bilmediğim ve bazı karakterleri kaybetmeyi umursamadığım sorunumu çözdü.
Edhowler

2

bu, ubuntu 15.10 için çalışır:

sudo locale-gen "en_US.UTF-8"
sudo dpkg-reconfigure locales

1

Dizeniz kodlanmış gibi görünüyor utf-8, peki sorun tam olarak nedir? Ya da burada ne yapmaya çalışıyorsun ..?

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'

Orijinal dizeyi olduğu gibi (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ëyazdırarak, doğru şekilde kodlamasını istiyorum.
Markum

1

Benim durumumda, bunun nedeni Unicode dosyamın bir "BOM" ile kaydedilmesiydi. Bunu çözmek için BBEdit kullanarak dosyayı kırdım ve "Unicode (UTF-8)" kodlamasını seçip "Unicode (UTF-8, BOM ile) olanı değil" Farklı kaydet ... "yaptım. "


0

Aynı tür bir hata alıyordum ve konsolun dizeyi başka bir dilde görüntüleyemediğini fark ettim. Bu nedenle, default_charset'i UTF-8 olarak ayarlamak için aşağıdaki kod değişikliklerini yaptım.

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 ])


-1

BOM, benim için çok sık BOM

vi dosyayı kullanın

:set nobomb

ve kaydedin. Bu neredeyse her zaman benim durumumda düzeltir


-1

Ascii olmayan karakterler içeren URL'lerde de aynı hatayı aldım (değerleri> 128 olan baytlar)

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

Benim için çalıştı, Python 2.7'de, bu atamanın strdahili gösterimde 'bir şeyi' değiştirdiğini düşünüyorum - yani, desteklenen bayt dizisinin doğru kod çözülmesini zorlar urlve sonunda dizeyi tüm sihirle bir utf-8'e koyar str. Doğru yer. Python'daki Unicode benim için kara büyüdür. Yararlı umut


-2

Bu sorunu settings.py dosyasında değiştirerek 'ENGINE': 'django.db.backends.mysql' ile çözüyorum, 'ENGINE' kullanmayın: 'mysql.connector.django',


@rayryeng Düzenlemenizin nedenini açıklayabilir misiniz? Belirli bir ayarı önermekten aleyhine tavsiyeye kadar OP'nin yazdıklarının anlamını tamamen değiştirdiği görülmektedir .
kimse

@AndrewMedico - Özür dilerim. Bu yazının bir başkasına çok benzediğini gördüm ve aynı olduklarına inandım. Geri döneceğim.
rayryeng

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.