如何修复:“UnicodeDecodeError:'ascii'编解码器无法解码字节”

时间:2014-01-15 04:15:37

标签: python python-2.7 chinese-locale

as3:~/ngokevin-site# nano content/blog/20140114_test-chinese.mkd
as3:~/ngokevin-site# wok
Traceback (most recent call last):
File "/usr/local/bin/wok", line 4, in
Engine()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 104, in init
self.load_pages()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 238, in load_pages
p = Page.from_file(os.path.join(root, f), self.options, self, renderer)
File "/usr/local/lib/python2.7/site-packages/wok/page.py", line 111, in from_file
page.meta['content'] = page.renderer.render(page.original)
File "/usr/local/lib/python2.7/site-packages/wok/renderers.py", line 46, in render
return markdown(plain, Markdown.plugins)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 419, in markdown
return md.convert(text)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 281, in convert
source = unicode(source)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128). -- Note: Markdown only accepts unicode input!

如何解决?

在其他一些基于python的静态博客应用中,可以成功发布中文帖子。 比如这个应用:http://github.com/vrypan/bucket3。在我的网站http://bc3.brite.biz/中,中文帖子可以成功发布。

19 个答案:

答案 0 :(得分:480)

最后我明白了:

as3:/usr/local/lib/python2.7/site-packages# cat sitecustomize.py
# encoding=utf8  
import sys  

reload(sys)  
sys.setdefaultencoding('utf8')

让我查一下:

as3:~/ngokevin-site# python
Python 2.7.6 (default, Dec  6 2013, 14:49:02)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.getdefaultencoding()
'utf8'
>>>

以上显示python的默认编码为utf8。然后错误就不复存在了。

答案 1 :(得分:121)

这是经典的“unicode问题”。我相信解释这一点超出了StackOverflow答案的范围,可以完全解释发生的事情。

很好地解释了here

在非常简短的总结中,您已将一些被解释为字节串的内容传递给需要将其解码为Unicode字符的内容,但默认编解码器(ascii)失败。

我指出的演示文稿提供了避免这种情况的建议。使您的代码成为“unicode三明治”。在Python 2中,使用“from __future__ import unicode_literals”会有所帮助。

更新:如何修复代码:

好的 - 在变量“source”中你有一些字节。从你的问题不清楚他们是如何进入那里的 - 也许你是从网络表格中读到的?在任何情况下,它们都不是用ascii编码的,但python试图将它们转换为unicode,假设它们是。您需要明确告诉它编码是什么。这意味着您需要知道编码是什么!这并不总是容易的,它完全取决于这个字符串的来源。您可以尝试一些常见的编码 - 例如UTF-8。你告诉unicode()编码作为第二个参数:

source = unicode(source, 'utf-8')

答案 2 :(得分:39)

在某些情况下,当您检查默认编码(print sys.getdefaultencoding())时,它会返回您使用的ASCII。如果更改为UTF-8,则它不起作用,具体取决于变量的内容。 我发现了另一种方式:

import sys
reload(sys)  
sys.setdefaultencoding('Cp1252')

答案 3 :(得分:17)

"UnicodeDecodeError: 'ascii' codec can't decode byte"

导致此错误的原因:input_string必须是unicode但是str已被赋予

"TypeError: Decoding Unicode is not supported"

此错误的原因:尝试将unicode input_string转换为unicode

首先检查您的input_string是否为str并在必要时转换为unicode:

if isinstance(input_string, str):
   input_string = unicode(input_string, 'utf-8')

其次,上面只是改变了类型但不删除非ascii字符。如果要删除非ascii字符:

if isinstance(input_string, str):
   input_string = input_string.decode('ascii', 'ignore').encode('ascii') #note: this removes the character and encodes back to string.

elif isinstance(input_string, unicode):
   input_string = input_string.encode('ascii', 'ignore')

答案 4 :(得分:16)

我正在搜索解决以下错误消息:

  

unicodedecodeerror:'ascii'编解码器无法解码5454位的字节0xe2:序号不在范围内(128)

我终于通过指定'encoding'来修复它:

f = open('../glove/glove.6B.100d.txt', encoding="utf-8")

希望它也可以帮到你。

答案 5 :(得分:8)

我发现最好总是转换为unicode - 但这很难实现,因为在实践中你必须检查并将每个参数转换为你编写的每个函数和方法,包括某种形式的字符串处理

所以我提出了以下方法来保证来自任一输入的unicodes或字符串。简而言之,include and use以下lambdas:

# guarantee unicode string
_u = lambda t: t.decode('UTF-8', 'replace') if isinstance(t, str) else t
_uu = lambda *tt: tuple(_u(t) for t in tt) 
# guarantee byte string in UTF8 encoding
_u8 = lambda t: t.encode('UTF-8', 'replace') if isinstance(t, unicode) else t
_uu8 = lambda *tt: tuple(_u8(t) for t in tt)

示例:

text='Some string with codes > 127, like Zürich'
utext=u'Some string with codes > 127, like Zürich'
print "==> with _u, _uu"
print _u(text), type(_u(text))
print _u(utext), type(_u(utext))
print _uu(text, utext), type(_uu(text, utext))
print "==> with u8, uu8"
print _u8(text), type(_u8(text))
print _u8(utext), type(_u8(utext))
print _uu8(text, utext), type(_uu8(text, utext))
# with % formatting, always use _u() and _uu()
print "Some unknown input %s" % _u(text)
print "Multiple inputs %s, %s" % _uu(text, text)
# but with string.format be sure to always work with unicode strings
print u"Also works with formats: {}".format(_u(text))
print u"Also works with formats: {},{}".format(*_uu(text, text))
# ... or use _u8 and _uu8, because string.format expects byte strings
print "Also works with formats: {}".format(_u8(text))
print "Also works with formats: {},{}".format(*_uu8(text, text))

这里还有一些reasoning about this

答案 6 :(得分:5)

Encode将unicode对象转换为字符串对象。我想你正在尝试编码一个字符串对象。首先将结果转换为unicode对象,然后将该unicode对象编码为'utf-8'。 例如

    result = yourFunction()
    result.decode().encode('utf-8')

答案 7 :(得分:3)

为了在Ubuntu安装中的操作系统级别解决此问题,请检查以下内容:

$ locale charmap

如果得到

locale: Cannot set LC_CTYPE to default locale: No such file or directory

代替

UTF-8

然后像这样设置LC_CTYPELC_ALL

$ export LC_ALL="en_US.UTF-8"
$ export LC_CTYPE="en_US.UTF-8"

答案 8 :(得分:3)

我遇到了同样的问题,但它对Python 3没有用。我按照这个并解决了我的问题:

enc = sys.getdefaultencoding()
file = open(menu, "r", encoding = enc)

您必须在读取/写入文件时设置编码。

答案 9 :(得分:2)

简而言之,要确保在Python 2中正确处理unicode:

  • 使用io.open来读取/写入文件
  • 使用from __future__ import unicode_literals
  • 配置其他数据输入/输出(例如,数据库,网络)以使用unicode
  • 如果您无法将输出配置为utf-8,请将输出转换为print(text.encode('ascii', 'replace').decode())

有关解释,请参阅@Alastair McCormack&#39; detailed answer

答案 10 :(得分:2)

我遇到了字符串“PastelerÃaMallorca”的同样问题,我解决了:

unicode("Pastelería Mallorca", 'latin-1')

答案 11 :(得分:1)

我也遇到了同样的错误,URL包含非ASCII字符(值大于128的字节)

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

注意:utf-8,utf8只是别名。仅使用“ utf8”或“ utf-8”应该以相同的方式工作

就我而言,在Python 2.7中为我工作,我认为此分配更改了str内部表示形式中的“某些内容”,即,它强制对{{1 }},最后将字符串放入 utf-8 url,并在正确的位置放置所有魔术。 Python中的Unicode对我来说是黑魔法。 希望有用

答案 12 :(得分:1)

当我们的字符串中包含一些非ASCII字符并且我们对该字符串执行任何操作而没有正确解码时,就会发生此错误。 这帮助我解决了我的问题。 我正在读取具有ID列,文本和解码字符的CSV文件,如下所示:

train_df = pd.read_csv("Example.csv")
train_data = train_df.values
for i in train_data:
    print("ID :" + i[0])
    text = i[1].decode("utf-8",errors="ignore").strip().lower()
    print("Text: " + text)

答案 13 :(得分:1)

在Django(1.9.10)/ Python 2.7.5项目中,我经常有UnicodeDecodeError个例外;主要是当我尝试将unicode字符串提供给日志记录时。我为任意对象创建了一个辅助函数,基本上格式化为8位ascii字符串,并将表中没有的任何字符替换为&#39;?&#39;。我认为它不是最好的解决方案,但由于默认编码是ascii(我不想改变它),它会做:

def encode_for_logging(c, encoding='ascii'):
    if isinstance(c, basestring):
        return c.encode(encoding, 'replace')
    elif isinstance(c, Iterable):
        c_ = []
        for v in c:
            c_.append(encode_for_logging(v, encoding))
        return c_
    else:
        return encode_for_logging(unicode(c))
`

答案 14 :(得分:0)

这是我的解决方案,只需添加编码即可。 with open(file, encoding='utf8') as f

由于读取手套文件会花费很长时间,因此我建议将手套文件转换为numpy文件。当您使用netx时间阅读嵌入权重时,它将节省您的时间。

import numpy as np
from tqdm import tqdm


def load_glove(file):
    """Loads GloVe vectors in numpy array.
    Args:
        file (str): a path to a glove file.
    Return:
        dict: a dict of numpy arrays.
    """
    embeddings_index = {}
    with open(file, encoding='utf8') as f:
        for i, line in tqdm(enumerate(f)):
            values = line.split()
            word = ''.join(values[:-300])
            coefs = np.asarray(values[-300:], dtype='float32')
            embeddings_index[word] = coefs

    return embeddings_index

# EMBEDDING_PATH = '../embedding_weights/glove.840B.300d.txt'
EMBEDDING_PATH = 'glove.840B.300d.txt'
embeddings = load_glove(EMBEDDING_PATH)

np.save('glove_embeddings.npy', embeddings) 

要害链接:https://gist.github.com/BrambleXu/634a844cdd3cd04bb2e3ba3c83aef227

答案 15 :(得分:0)

在Python文件顶部指定:#encoding = utf-8 ,它应该可以解决问题

答案 16 :(得分:0)

遇到了同样的错误,这解决了我的错误。谢谢! python 2和python 3在unicode处理方面的不同使腌制的文件与加载完全不兼容。因此,请使用python pickle的encoding参数。当我尝试从python 3.7中打开腌制数据时,下面的链接帮助我解决了类似的问题,而我的文件最初保存在python 2.x版本中。 https://blog.modest-destiny.com/posts/python-2-and-3-compatible-pickle-save-and-load/ 我在脚本中复制load_pickle函数,并在加载输入数据时调用load_pickle(pickle_file),如下所示:

input_data = load_pickle("my_dataset.pkl")

load_pickle函数在这里:

def load_pickle(pickle_file):
    try:
        with open(pickle_file, 'rb') as f:
            pickle_data = pickle.load(f)
    except UnicodeDecodeError as e:
        with open(pickle_file, 'rb') as f:
            pickle_data = pickle.load(f, encoding='latin1')
    except Exception as e:
        print('Unable to load data ', pickle_file, ':', e)
        raise
    return pickle_data

答案 17 :(得分:0)

这对我有用:

    file = open('docs/my_messy_doc.pdf', 'rb')

答案 18 :(得分:0)

我在使用 Python2.7 时遇到了这个错误。我在尝试运行许多 python 程序时发生了这种情况,但我设法用这个简单的脚本重现了它:

#!/usr/bin/env python

import subprocess
import sys

result = subprocess.Popen([u'svn', u'info'])
if not callable(getattr(result, "__enter__", None)) and not callable(getattr(result, "__exit__", None)):
    print("foo")
print("bar")

如果成功,它应该打印出“foo”和“bar”,如果您不在 svn 文件夹中,则可能会显示一条错误消息。

失败时,它应该打印'UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 39: ordinal not in range(128)'

在尝试重新生成我的语言环境和此问题中发布的许多其他解决方案后,我了解到错误的发生是因为我的 PATH 环境变量中编码了一个特殊字符 (ĺ)。在 '~/.bashrc' 中修复 PATH 并退出我的会话并再次进入后,(显然采购 '~/.bashrc' 不起作用),问题消失了。