Am câteva probleme în încercarea de a codifica un șir de caractere în UTF-8. Am încercat numeroase lucruri, inclusiv să folosesc string.encode('utf-8')
și unicode(string)
, , dar primesc eroarea:
UnicodeDecodeError: codecul ‘ascii’ nu poate decoda octetul 0xef în poziția 1: ordinal nu se află în intervalul (128).
Acesta este șirul meu de caractere:
(。・ω・。)ノ
Nu văd ce nu merge bine, vreo idee?
Edit: Problema este că imprimarea șirului așa cum este nu se afișează corect. De asemenea, această eroare când încerc să îl convertesc:
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 = '(xefxbdxa1xefxbdxa5xcfx89xefxbdxa5xefxbdxa1)xefxbex89'
>>> 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)
- Este doar un șir de caractere inserat normal. Același lucru se întâmplă și atunci când încerc doar să îl imprim. – > Por Markum.
- Întâlnesc același lucru atunci când instalez pip, și îl rezolv de aici: [install some devel][1] [1] [1]: stackoverflow.com/questions/17931726/… > Por BollMose.
Acest lucru are legătură cu faptul că codificarea terminalului dvs. nu este setată la UTF-8. Aici este terminalul meu
$ 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 = '(xefxbdxa1xefxbdxa5xcfx89xefxbdxa5xefxbdxa1)xefxbex89'
>>> s1 = s.decode('utf-8')
>>> print s1
(。・ω・。)ノ
>>>
Pe terminalul meu, exemplul funcționează cu cele de mai sus, dar dacă scap de LANG
atunci nu va funcționa
$ 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 = '(xefxbdxa1xefxbdxa5xcfx89xefxbdxa5xefxbdxa1)xefxbex89'
>>> 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)
>>>
Consultați documentația pentru varianta dvs. de linux pentru a descoperi cum să faceți această modificare permanentă.
- Locațiile lipsă ar putea fi, de asemenea, un motiv. Pentru a le instala, rulați
sudo apt-get install language-pack-de
sausudo locale-gen de_DE.UTF-8
(pentru locale germane). – > . - Pentru mine, variabila de mediu care lipsește este
LC_ALL
, , iar cea mai simplă valoare care ar rezolva problema esteC.UTF-8
– > .
încercați:
string.decode('utf-8') # or:
unicode(string, 'utf-8')
editați:
'(xefxbdxa1xefxbdxa5xcfx89xefxbdxa5xefxbdxa1)xefxbex89'.decode('utf-8')
dă u'(uff61uff65u03c9uff65uff61)uff89'
, , ceea ce este corect.
deci problema dvs. trebuie să fie în alt loc, probabil dacă încercați să faceți ceva cu el, unde are loc o conversie implicită (ar putea fi vorba de imprimare, scriere într-un flux…).
pentru a spune mai multe, va trebui să vedem niște cod.
- Ambele returnează
UnicodeEncodeError: 'charmap' codec can't encode characters in position 1-5: character maps to <undefined>
– > . '(xefxbdxa1xefxbdxa5xcfx89xefxbdxa5xefxbdxa1)xefxbex89'
– > .- Tot ceea ce încerc să fac este să tipăresc șirul original în formatul său original, dar primesc
(´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë
. – > . - the
string
este codat utf8. dacă îl tipăriți, acesta doar trimite octeții în fluxul de ieșire, iar dacă terminalul dvs. nu îl interpretează ca utf8, veți obține un gunoi. cudecode
îl convertiți în unicode, atunci putețiencode
din nou într-o codificare pe care terminalul dvs. o înțelege. – > .
+1 la comentariul lui mata de la https://stackoverflow.com/a/10561979/1346705 și la demonstrația lui Nick Craig-Wood. Ați decodificat corect șirul de caractere. Problema este cu print
deoarece aceasta convertește șirul Unicode în codificarea consolei, iar consola nu este capabilă să afișeze șirul. Încercați să scrieți șirul într-un fișier și să vă uitați la rezultat folosind un editor decent care acceptă Unicode:
import codecs
s = '(xefxbdxa1xefxbdxa5xcfx89xefxbdxa5xefxbdxa1)xefxbex89'
s1 = s.decode('utf-8')
f = codecs.open('out.txt', 'w', encoding='utf-8')
f.write(s1)
f.close()
Apoi veți vedea (。・ω・。)ノ
.
Dacă lucrați la un fișier la distanță gazdă, uitați-vă la /etc/ssh/ssh_config
pe calculatorul dvs. locală PC.
Atunci când acest fișier conține o linie:
SendEnv LANG LC_*
comentați-o adăugând #
la începutul liniei. Ar putea fi de ajutor.
Cu această linie, ssh
trimite variabilele de mediu legate de limbă ale PC-ului dvs. către la distanță de la distanță. Aceasta determină o mulțime de probleme.
- Vă mulțumim! Acestea au rezolvat problema pe care o aveam la instalarea pachetelor pip cu ansible și vagrant – > .
Încercați să setați codificarea implicită a sistemului ca fiind utf-8
la începutul scriptului, astfel încât toate șirurile de caractere să fie codificate folosind acest lucru.
# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
- de ce avem nevoie de reîncărcare în acest caz? – > .
- Acest lucru nu funcționează în Python 3, așa cum se explică aici. Pentru mine, răspunsul lui Tsutomu de mai jos a rezolvat problema. – > .
Este bine să folosiți codul de mai jos în partea de sus a scriptului dvs. așa cum a sugerat Andrei Krasutski.
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
Dar vă voi sugera să adăugați și # -*- coding: utf-8 -*
linie chiar în partea de sus a scriptului.
Omiterea acesteia aruncă eroarea de mai jos, în cazul meu, atunci când încerc să o execut 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
Următorul este codul prezent în basic.py
care aruncă eroarea de mai sus.
codul cu eroare
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)
Apoi am adăugat # -*- coding: utf-8 -*-
linia în partea de sus și am executat. A funcționat.
cod fără eroare
# -*- 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)
Mulțumesc.
- Folosind
#coding: utf-8
în loc de# -*- coding: utf-8 -*-
acest lucru este mai ușor de reținut. Funcționează din start cu Python PEP 263 — Definirea codurilor de cod sursă Python. – > . - Vă mulțumim pentru sugestie. Voi încerca la mine și o voi actualiza în răspuns. – > .
Nici o problemă cu terminalul meu. Răspunsurile de mai sus m-au ajutat să caut în direcțiile corecte, dar nu a funcționat pentru mine până când nu am adăugat 'ignore'
:
fix_encoding = lambda s: s.decode('utf8', 'ignore')
După cum se indică în comentariul de mai jos, acest lucru poate duce la rezultate nedorite. OTOH, de asemenea, este posibil să fie suficient de bine pentru ca lucrurile să funcționeze și să nu vă pese de pierderea unor caractere.
- Acest lucru este greșit, forțați funcția lambda de codificare să ignore codificarea însăși, ceea ce înseamnă că pierdeți caractere. – > .
- Acest lucru a rezolvat problema mea, în care nu cunoșteam codificarea originală și nu-mi păsa de pierderea unor caractere. – > .
acest lucru funcționează pentru ubuntu 15.10:
sudo locale-gen "en_US.UTF-8"
sudo dpkg-reconfigure locales
Se pare că șirul dvs. este codificat la utf-8
, , deci care este exact problema? Sau ce încerci să faci aici…?
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 = '(xefxbdxa1xefxbdxa5xcfx89xefxbdxa5xefxbdxa1)xefxbex89'
>>> s1 = s.decode('utf-8')
>>> print s1
(。・ω・。)ノ
>>> s2 = u'(。・ω・。)ノ'
>>> s2 == s1
True
>>> s2
u'(uff61uff65u03c9uff65uff61)uff89'
- Tipărirea șirului original așa cum este, dă
(´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë
, , vreau să se codifice corect. – > .
În cazul meu, a fost cauzat de faptul că fișierul meu Unicode a fost salvat cu un „BOM”. Pentru a rezolva acest lucru, am crăpat fișierul deschis folosind BBEdit și am făcut un „Save as…” alegând pentru codificarea „Unicode (UTF-8)” și nu ceea ce a venit cu care a fost „Unicode (UTF-8, cu BOM)”
Am primit același tip de eroare și am constatat că consola nu este capabilă să afișeze șirul în altă limbă. Prin urmare, am făcut modificările de cod de mai jos pentru a seta default_charset ca UTF-8.
data_head = [('x81xa1x8fox89xefx82xa2x95xdbx8fxd8x90xa7x93xx81xcb3x8cx8ex8cpx91xb1x92x86(x81x86x81xdex81x85)x81xa1x8fx89x89xf1x88xc8x8aOx81Ax82xa8x8bxe0x82xccx90Sx94zx82xcdx88xeax90xd8x95sx97vx81xa1x83}x83bx83vx82xccx82xa8x8ex8ex82xb5x95xdbx8cxafx82xc5x8fox89xefx82xa2x8amx92xe8x81xa1', '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 ])
Acesta este cel mai bun răspuns:https://stackoverflow.com/a/4027726/2159089
în linux:
export PYTHONIOENCODING=utf-8
deci sys.stdout.encoding
este OK.
BOM, este atât de des BOM pentru mine
vi fișierul, utilizați
:set nobomb
și salvați-l. În cazul meu, asta aproape întotdeauna rezolvă problema
Am avut aceeași eroare, cu URL-uri care conțin caractere non-ascii (bytes cu valori > 128)
url = url.decode('utf8').encode('utf-8')
A funcționat pentru mine, în Python 2.7, presupun că această atribuție a schimbat „ceva” în str
reprezentarea internă – adică forțează decodarea corectă a secvenței de octeți susținută în url
și, în cele din urmă, pune șirul într-un utf-8 str
cu toată magia la locul potrivit.Unicode în Python este magie neagră pentru mine.Sper că este utilă
am rezolvat această problemă schimbând în fișierul settings.py cu ‘ENGINE’: ‘django.db.backends.mysql’, nu folosiți ‘ENGINE’: ‘mysql.connector.django’,
- @rayryeng Poți să explici motivul modificării tale? Se pare că se schimbă complet sensul a ceea ce a scris OP, de la recomandarea unei anumite setări la recomandarea împotriva acesteia. – > .
- @AndrewMedico – Îmi cer scuze. Am văzut că această postare era foarte asemănătoare cu o alta, așa că am crezut că sunt identice. Voi reveni înapoi. – > .
Doar convertiți textul în mod explicit în șir de caractere folosind str()
. A funcționat pentru mine.