How to fix: “UnicodeDecodeError: 'ascii' codec can't decode byte”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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/,中文帖子可以成功发布。
我终于明白了:
1 2 3 4 5 6 | as3:/usr/local/lib/python2.7/site-packages# cat sitecustomize.py # encoding=utf8 import sys reload(sys) sys.setdefaultencoding('utf8') |
让我检查一下:
1 2 3 4 5 6 7 8 9 10 | 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的默认编码是
型不要使用流行的答案(
这是一个令人讨厌的黑客行为(你必须使用
- 百万千克1不要随意解码/编码百万千克1百万千克1不要假设字符串是UTF-8编码的百万千克1百万千克1尝试在代码中尽快将字符串转换为Unicode字符串百万千克1百万千克1修复您的区域设置:如何解决python 3.6中的unicodedecode错误?百万千克1
型python 2.x中的unicode zen-长版本
如果没有找到源头,就很难知道根本原因,所以我得通盘谈谈。好的。型
当您试图将包含非ASCII的python 2.x
简而言之,Unicode字符串是一种完全独立的Python字符串类型,不包含任何编码。它们只保存Unicode点代码,因此可以在整个频谱中保存任何Unicode点。字符串包含编码文本、beit utf-8、utf-16、iso-8895-1、gbk、big5等。字符串解码为Unicode,单码编码为字符串。文件和文本数据总是以编码字符串的形式传输。好的。型
Markdown模块的作者可能使用
可以使用字符串的
1 2 3 | >>> my_u = u'my ünic?dé str?ng' >>> type(my_u) <type 'unicode'> |
Unicode字符串也可能来自文件、数据库和网络模块。当发生这种情况时,您不需要担心编码问题。好的。型戈查斯
即使不显式调用
以下情况导致
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # Explicit conversion without encoding unicode('€') # New style format string into Unicode string # Python will try to convert value string to Unicode first u"The currency is: {}".format('€') # Old style format string into Unicode string # Python will try to convert value string to Unicode first u'The currency is: %s' % '€' # Append string to Unicode # Python will try to convert string to Unicode first u'The currency is: ' + '€' |
号示例
在下图中,您可以看到单词
在这个图中,用
氧化镁好的。Unicode三明治
在代码中形成一个Unicode三明治是一个很好的实践,在代码中将所有传入的数据解码为Unicode字符串,使用unicode s,然后在退出时编码到
如果需要将非ASCII烘焙到源代码中,只需在字符串前加一个
1 | u'Zürich' |
要允许python解码源代码,您需要添加一个编码头来匹配文件的实际编码。例如,如果您的文件编码为"utf-8",您将使用:好的。
1 | # encoding: utf-8 |
只有在源代码中有非ASCII码时才需要这样做。好的。文件夹
通常从文件接收非ASCII数据。
1 2 3 | import io with io.open("my_utf8_file.txt","r", encoding="utf-8") as my_file: my_unicode_string = my_file.read() |
那么,
python 2.7 csv模块不支持非ASCII字符??然而,通过https://pypi.python.org/pypi/backports.csv,帮助就在眼前。好的。
像上面一样使用它,但将打开的文件传递给它:好的。
1 2 3 4 5 | from backports import csv import io with io.open("my_utf8_file.txt","r", encoding="utf-8") as my_file: for row in csv.reader(my_file): yield row |
数据库
大多数python数据库驱动程序可以用unicode返回数据,但通常需要一些配置。SQL查询总是使用Unicode字符串。好的。MySQL
在连接字符串中添加:好的。
1 2 | charset='utf8', use_unicode=True |
例如。好的。
1 | >>> db = MySQLdb.connect(host="localhost", user='root', passwd='passwd', db='sandbox', use_unicode=True, charset="utf8") |
波斯特雷斯尔
添加:好的。
1 2 | psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY) |
超文本传输协议
网页可以用几乎任何编码进行编码。
如果必须手动解码字符串,则只需执行
像处理普通的str一样处理unicodes。好的。产量标准输出/打印
配置不正确的控制台(如损坏的区域设置)可能导致意外的打印错误。
就像输入一样,
相同的读取配置将允许直接写入单码。好的。Python 3
python 3不再像python 2.x那样支持Unicode,但是常规的
默认的编码现在是UTF-8,因此如果您在不提供编码的情况下
此外,默认情况下,
这是典型的"Unicode问题"。我认为,解释这一点超出了StackOverflow答案的范围,无法完全解释正在发生的事情。
这里解释得很清楚。
在非常简短的总结中,您已经将一些被解释为字节字符串的内容传递给了一些需要将其解码为Unicode字符的内容,但是默认的编解码器(ASCII)失败了。
我指给你的演讲为避免这种情况提供了建议。使代码成为"Unicode三明治"。在python 2中,使用"从未来导入unicode文本"有帮助。
更新:如何修复代码:
好的-在变量"source"中有一些字节。从你的问题中还不清楚他们是如何进入的-也许你是从一个网络表单中读到的?在任何情况下,它们都不是用ASCII编码的,但python尝试将它们转换为Unicode,前提是它们是这样的。您需要明确地告诉它编码是什么。这意味着您需要知道编码是什么!这并不总是容易的,它完全取决于这个字符串的来源。您可以使用一些常见的编码进行试验,例如utf-8。将编码作为第二个参数告诉unicode():
1 | source = unicode(source, 'utf-8') |
在某些情况下,当您检查默认编码(
1 2 3 | import sys reload(sys) sys.setdefaultencoding('Cp1252') |
1 | "UnicodeDecodeError: 'ascii' codec can't decode byte" |
此错误的原因:输入字符串必须是Unicode,但给出了str
1 | "TypeError: Decoding Unicode is not supported" |
此错误的原因:试图将Unicode输入字符串转换为Unicode
因此,首先检查您的输入字符串是
1 2 | if isinstance(input_string, str): input_string = unicode(input_string, 'utf-8') |
其次,上面只更改了类型,但没有删除非ASCII字符。如果要删除非ASCII字符:
1 2 3 4 5 | 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') |
我正在搜索以解决以下错误消息:
unicodedecodeerror: 'ascii' codec can't decode byte 0xe2 in position 5454: ordinal not in range(128)
我最后通过指定"编码"来修复它:
1 | f = open('../glove/glove.6B.100d.txt', encoding="utf-8") |
希望它也能帮助你。
我发现最好的方法是始终转换为Unicode,但这很难实现,因为在实践中,您必须检查每个参数,并将其转换为您曾经编写的每个函数和方法,其中包括某种形式的字符串处理。
因此,我提出了以下方法来保证来自任一输入的单码或字节字符串。简而言之,包括并使用以下lambda:
1 2 3 4 5 6 | # 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) |
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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)) |
下面是关于这个的一些更多的理由。
Encode将中的Unicode对象转换为字符串对象。我认为您正在尝试对字符串对象进行编码。首先将结果转换为Unicode对象,然后将该Unicode对象编码为"utf-8"。例如
1 2 | result = yourFunction() result.decode().encode('utf-8') |
要在Ubuntu安装的操作系统级别上解决此问题,请检查以下内容:
1 | $ locale charmap |
如果你得到
1 | locale: Cannot set LC_CTYPE to default locale: No such file or directory |
而不是
1 | UTF-8 |
然后将
1 2 | $ export LC_ALL="en_US.UTF-8" $ export LC_CTYPE="en_US.UTF-8" |
我也有同样的问题,但它不适用于Python3。我按照这个方法解决了我的问题:
1 2 | enc = sys.getdefaultencoding() file = open(menu,"r", encoding = enc) |
在读/写文件时,必须设置编码。
简而言之,为了确保在python 2中正确地处理unicode:
- 使用
io.open 读取/写入文件 - 使用
from __future__ import unicode_literals 。 - 配置其他数据输入/输出(如数据库、网络)以使用Unicode
- 如果无法将输出配置为utf-8,请将输出转换为
print(text.encode('ascii', 'replace').decode()) 。
有关解释,请参见@alastair mccormack's detailed answer。
我对弦乐"粉笔机"也有同样的问题。-一个马洛卡",我解决了:
1 | unicode("Pasteler?-a Mallorca", 'latin-1') |
在django(1.9.10)/python 2.7.5项目中,我经常遇到
1 2 3 4 5 6 7 8 9 10 | 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)) |
我也有同样的错误,URL包含非ASCII字符(值大于128的字节)
1 | url = url.decode('utf8').encode('utf-8') |
注意:utf-8、utf8只是别名。只使用"utf8"或"utf-8"应该以同样的方式工作
在我的例子中,在python 2.7中,我认为这个分配改变了
当我们的字符串中有一些非ASCII字符,并且我们在没有正确解码的情况下对该字符串执行任何操作时,就会发生此错误。这帮助我解决了我的问题。我正在读取一个csv文件,其中包含列id、文本和解码字符,如下所示:
1 2 3 4 5 6 | 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) |
这是我的解决方案,只需添加编码。
而且因为读手套文件需要很长时间,我建议把手套文件变成一个麻木的文件。当netx time读取嵌入权重时,它将节省您的时间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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) |
gist链接:https://gist.github.com/bramblexu/634a844cd3cd04bb2e3ba3c83aef277
在python文件的顶部指定:encoding=utf-8,它应该解决这个问题。