UnicodeDecodeError: 'ascii' 编解码器无法在位置1处解码字节0xef

113

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

UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 1: ordinal not in range(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)

这只是一个普通的插入字符串。当我尝试打印它时,情况也是一样的。 - Markum
我在使用pip install时遇到了相同的问题,并从这里解决:安装一些devel - BollMose
16个回答

74

这与您的终端编码设置为非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设置,示例就可以工作。但是,如果我不使用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(适用于德语本地化)。 - Non
对我来说,缺失的环境变量是 LC_ALL,最简单的修复值是 C.UTF-8 - Robin Winslow

25

尝试:

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' 编解码器无法编码第1-5个位置的字符:该字符映射到 <未定义> - Markum
'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89' - Markum
1
我所尝试做的就是以原始格式输出字符串,但是我却得到了(´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë - Markum
4
string是以UTF-8编码的。如果您将其打印出来,它只会将字节写入输出流,如果您的终端不将其解释为UTF-8,则会出现垃圾字符。通过使用decode将其转换为Unicode,然后可以再次使用适合您终端理解的编码进行encode - mata

22

我支持mata在https://dev59.com/jGkv5IYBdhLWcg3wfA0P#10561979中的评论以及Nick Craig-Wood的演示。你已经正确解码了字符串。问题出在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

在脚本开始时,尝试将系统默认编码设置为utf-8,这样所有字符串都将使用该编码进行编码。

# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

在这种情况下,我们为什么需要重新加载? - fallingdog
这在Python 3中不起作用,原因在此处解释。对我来说,下面的答案,Tsutomu的回答解决了问题。 - Piyush Goel

10
如果您正在使用远程主机,请查看本地计算机上的/etc/ssh/ssh_config文件。
当此文件包含以下行时:
SendEnv LANG LC_*

在行首添加#可将其注释掉,这可能会有所帮助。

ssh发送与语言相关的环境变量到远程主机。它会引起很多问题。


谢谢!这些解决了我在使用Ansible和Vagrant安装pip软件包时遇到的问题。 - Maritza Esparza

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 -- Defining Python Source Code Encodings 标准,可直接在 Python 中使用。 - Andrei Krasutski
感谢您的建议。我会在我的端上尝试并在回答中更新它。 - hygull

4

我的终端没有问题。上面的答案帮助我找到了正确的方向,但在我添加 'ignore' 之前它对我没有用:

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

正如下面的评论所指出的那样,这可能会导致一些不理想的结果。另一方面,它也可能会很好地完成任务并使事情运作起来,您可能并不在意失去一些字符。

2
这是错误的,你正在强制编码lambda函数忽略编码本身,这意味着你会丢失字符。 - Maximiliano Rios
2
这解决了我的问题,我不知道原始编码,也不在意丢失一些字符。 - Edhowler

2

这适用于Ubuntu 15.10:

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

1
在我的情况下,这是由于我的Unicode文件保存了“BOM”引起的。要解决这个问题,我使用BBEdit打开文件,并执行“另存为...”,选择编码为“Unicode(UTF-8)”,而不是它原来的“Unicode(UTF-8,带BOM)”。

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'

将原始字符串按原样打印会得到(´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë,我希望它能正确编码。 - Markum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接