UnicodeDecodeError:“ ascii”编解码器无法解码位置1的字节0xef


106

我在尝试将字符串编码为UTF-8时遇到一些问题。我已经尝试了很多事情,包括使用string.encode('utf-8')unicode(string),但是出现错误:

UnicodeDecodeError:'ascii'编解码器无法解码位置1的字节0xef:序数不在范围内(128)

这是我的字符串:

(。・ω・。)ノ

我看不出怎么了,知道吗?

编辑:问题是按原样打印字符串无法正确显示。此外,当我尝试将其转换为此错误时:

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)

这只是正常插入的字符串。当我尝试打印时也会发生同样的情况。
马库姆

我见面的时候PIP安装,并从这里修复相同:安装一些devel的] [1] [1]:stackoverflow.com/questions/17931726/...
BollMose

Answers:


70

这与终端的编码未设置为UTF-8有关。这是我的航站楼

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

在我的终端上,该示例适用于上面的示例,但是如果我摆脱了LANG设置,那么它将无法正常工作

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

请查阅适用于您的Linux变体的文档,以了解如何使此更改永久生效。


1
缺少语言环境也可能是原因。要安装它们,请运行sudo apt-get install language-pack-desudo locale-gen de_DE.UTF-8(对于德国语言环境)。

对我来说,缺少的环境变量是LC_ALL,并且解决该问题的最简单的值是C.UTF-8
Robin Winslow

24

尝试:

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

编辑:

'(\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',这是正确的。

因此您的问题一定在其他地方,如果您尝试执行某项操作(如果正在进行隐式转换)(可能是打印,写入流...)

多说些,我们需要看一些代码。


双方都回来了UnicodeEncodeError: 'charmap' codec can't encode characters in position 1-5: character maps to <undefined>
马库姆

'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
马库姆

1
我要做的就是以原始格式打印原始字符串,但是我得到了(´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë
马库姆

4
string是UTF8编码。如果您将其打印出来,它只会将字节写入输出流中,并且如果您的终端没有将其解释为utf8,您最终会得到垃圾。以decode将其转换为Unicode,那么你就可以encode再次到编码终端理解。
马塔2012年

21

我对https://stackoverflow.com/a/10561979/1346705上mata的评论以及尼克·克雷格·伍德的演示+1 。您已正确解码了字符串。问题出在print命令上,因为它将Unicode字符串转换为控制台编码,并且控制台无法显示该字符串。尝试将字符串写入文件,然后使用一些支持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()

然后您会看到(。・ω・。)ノ


10

如果您正在使用远程主机,请在本地 PC /etc/ssh/ssh_config上查看。

当该文件包含一行时:

SendEnv LANG LC_*

#在行的开头添加注释。这可能会有所帮助。

通过此行,ssh将PC的与语言相关的环境变量发送到远程主机。这会引起很多问题。


谢谢!这解决了我曾与ansible和流浪汉安装PIP封装问题
马里查埃斯帕扎


5

Andrei Krasutski建议的那样,可以在脚本顶部使用以下代码。

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

但是我建议您# -*- coding: utf-8 -*在脚本的最上方添加一行。

当我尝试执行时,忽略它会在错误的情况下抛出以下错误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

以下是当前代码,basic.py其中引发上述错误。

错误代码

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)

然后我# -*- coding: utf-8 -*-在最上方添加一行并执行。有效。

代码无错误

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

谢谢。


1
使用 #coding: utf-8而不是# -*- coding: utf-8 -*- 简单记住。可与Python PEP 263即用即用-定义Python源代码编码
Andrei Krasutski

谢谢你的建议。我会尽力尝试一下,并在答案中进行更新。
hygull

4

我的终端没问题。上面的答案帮助我朝正确的方向看,但是直到我添加'ignore'以下内容后,它才对我有用:

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

如以下评论中所述,这可能会导致不良结果。OTOH,它也可能足以使事情正常进行,并且您不必担心丢失某些角色。


2
这是错误的,您要强制编码lambda函数忽略编码本身,这意味着您将丢失字符。
Maximiliano Rios 2014年

2
这解决了我的问题,我不知道原始编码,也不在乎丢失一些字符。
Edhowler '17

2

这适用于Ubuntu 15.10:

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

1

看来您的字符串已编码为utf-8,那么究竟是什么问题呢?或者您想在这里做什么?

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'

按原样打印原始字符串(´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë,我希望它正确编码。
马库姆

1

就我而言,这是由于我的Unicode文件以“ BOM”保存。为了解决这个问题,我使用BBEdit打开了文件,并选择了“另存为...”来选择编码“ Unicode(UTF-8)”,而不是“ Unicode(UTF-8,带BOM)” ”


0

我遇到了相同类型的错误,并且发现控制台无法以其他语言显示字符串。因此,我进行了以下代码更改,以将default_charset设置为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 ])


-1

BOM,对我来说通常是BOM

vi文件,使用

:set nobomb

并保存。就我而言,几乎总是可以解决


-1

我遇到了相同的错误,URL包含非ASCII字符(值> 128的字节)

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

为我工作,在Python 2.7中,我认为此分配更改了str内部表示形式中的“某些内容” -即,它强制对后备字节序列进行正确的解码,url并最终将字符串放入utf-8中, str其中包含所有魔术正确的地方。Python中的Unicode对我来说是黑魔法。希望有用


-2

我用'ENGINE':'django.db.backends.mysql'解决了在文件settings.py中更改的问题,不要使用'ENGINE':'mysql.connector.django',


@rayryeng您能解释一下编辑原因吗?这似乎彻底改变的OP写的是什么意思,从推荐特定的设置,推荐反对它。
没人

@AndrewMedico-我很抱歉。我看到这篇文章与另一篇文章非常相似,因此我认为它们是相同的。我会回复原状。
rayryeng 2014年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.