编码给出“'ascii'编解码器无法编码字符......序数不在范围内(128)”

Posted

技术标签:

【中文标题】编码给出“\'ascii\'编解码器无法编码字符......序数不在范围内(128)”【英文标题】:Encoding gives "'ascii' codec can't encode character … ordinal not in range(128)"编码给出“'ascii'编解码器无法编码字符......序数不在范围内(128)” 【发布时间】:2011-01-31 13:34:06 【问题描述】:

我正在研究 Django RSS 阅读器项目here。

RSS 提要将显示类似“OKLAHOMA CITY (AP) — James Harden let”的内容。 RSS 提要的编码读取 encoding="UTF-8" 所以我相信我在下面的代码 sn-p 中将 utf-8 传递给 markdown。破折号是它窒息的地方。

我收到 Django 错误“'ascii'编解码器无法在位置 109 编码字符 u'\u2014':序数不在范围 (128)”,这是一个 UnicodeEncodeError。在传递的变量中,我看到“OKLAHOMA CITY (AP) \u2014 James Harden”。不工作的代码行是:

content = content.encode(parsed_feed.encoding, "xmlcharrefreplace")

我正在使用 markdown 2.0、django 1.1 和 python 2.4。

要完成这项工作,我需要执行什么神奇的编码和解码序列?


(应普罗米修斯的要求。我同意格式有帮助)

所以在视图中,我在 parsed_feed 编码行上方添加了 smart_unicode 行...

content = smart_unicode(content, encoding='utf-8', strings_only=False, errors='strict')
content = content = content.encode(parsed_feed.encoding, "xmlcharrefreplace") 

这将问题推到了我的models.py 中

def save(self, force_insert=False, force_update=False): 
     if self.excerpt: 
         self.excerpt_html = markdown(self.excerpt) 
         # super save after this 

如果我将保存方法更改为...

def save(self, force_insert=False, force_update=False): 
     if self.excerpt: 
         encoded_excerpt_html = (self.excerpt).encode('utf-8') 
         self.excerpt_html = markdown(encoded_excerpt_html)

我收到错误 "'ascii' codec can't decode byte 0xe2 in position 141: ordinal not in range(128)" 因为现在它读取 "\xe2\x80\x94" 其中破折号是

【问题讨论】:

能否按原样发布回溯? 基本上parsed_feed.encoding的值是多少?它是'ascii',有机会吗? (这可以解释你的两个错误)。 【参考方案1】:

如果您接收的数据实际上是用 UTF-8 编码的,那么它应该是一个字节序列——在 Python 2.X 中是一个 Python 'str' 对象

您可以通过断言来验证这一点:

assert isinstance(content, str)

一旦您知道这是真的,您就可以转到实际的编码。 Python 不进行转码——例如直接从 UTF-8 到 ASCII。您需要首先通过解码将字节序列转换为 Unicode 字符串:

unicode_content = content.decode('utf-8')

(如果您可以信任 parsed_feed.encoding,则使用它而不是文字 'utf-8'。无论哪种方式,都要为错误做好准备。)

然后您可以获取该字符串,并将其编码为 ASCII,用它们的 XML 实体等效项替换高字符:

xml_content = unicode_content.encode('ascii', 'xmlcharrefreplace')

那么,完整的方法如下所示:

try:
    content = content.decode(parsed_feed.encoding).encode('ascii', 'xmlcharrefreplace')
except UnicodeDecodeError:
    # Couldn't decode the incoming string -- possibly not encoded in utf-8
    # Do something here to report the error

【讨论】:

【参考方案2】:

Django provides a couple of useful functions for converting back and forth between Unicode and bytestrings:

从 django.utils.encoding 导入 smart_unicode, smart_str

【讨论】:

使用... content = smart_unicode(content, encoding='utf-8', strings_only=False, errors='strict') content = content = content.encode(parsed_feed.encoding, "xmlcharrefreplace ") 将问题推到我的 models.py 中我有 def save(self, force_insert=False, force_update=False): if self.excerpt: self.excerpt_html = markdown(self.excerpt) # super save after this If我将保存方法更改为 encode_excerpt_html = (self.excerpt).encode('utf-8') self.excerpt_html = markdown(encoded_excerpt_html) 第 2 部分:我收到错误“'ascii' codec can't decode byte 0xe2 in position 141: ordinal not in range(128)”,因为现在它显示为“\xe2\x80\x94”破折号在哪里。 你能用上面的内容修改你原来的帖子吗?没有正确的格式很难阅读。【参考方案3】:

我在使用 zip 文件写入文件名时遇到了这个错误。以下失败

ZipFile.write(root+'/%s'%file, newRoot + '/%s'%file)

以下工作

ZipFile.write(str(root+'/%s'%file), str(newRoot + '/%s'%file))

【讨论】:

对带有非 ASCII 字符的 unicode 值调用 str() 会导致 OP 看到的错误完全相同。 @MartijnPieters:您好,这是您提出的一个非常重要的观点。我找不到任何关于str() 在the fine manual 中实际所做的参考,但是我将其归因于我是一个 Python 菜鸟,而不是手册的错误。这在哪里记录,str() 到底对参数做了什么,str() 到底返回了什么?谢谢! str() 返回一个字节串;值介于 0 和 255 之间的字符,通常将 0-127 解释和显示为 ASCII 字符。另一方面,unicode() 值可以表示 Unicode 标准中的任何代码点,介于 0 和 1114111 之间。因此使用str(unicodevalue) 将 unicode 转换为字节字符串将涉及 some 转换. unicode 类型在 C 中实现,但它提供了与 __str__ 挂钩的 C API 等效项来进行转换; implementation 调用PyUnicode_AsEncodedString(),并且该函数使用PyUnicode_GetDefaultEncoding();猜猜那个函数是做什么的。 :-) 由于您无法将编码传递给str(),因此Python别无选择,只能使用默认编码。因此,当您需要后者时,显式编码为字节字符串总是更好。不要使用str(unicodevalue);这很少是一个好主意。

以上是关于编码给出“'ascii'编解码器无法编码字符......序数不在范围内(128)”的主要内容,如果未能解决你的问题,请参考以下文章

UnicodeEncodeError:“ascii”编解码器无法编码字符

Python3'ascii'编解码器无法编码字符

UnicodeEncodeError: 'ascii' 编解码器无法编码字符 u'\u2026'

UnicodeEncodeError: 'ascii' 编解码器无法编码字符 u'\u2013'

ascii' 编解码器无法编码字符 u'\xe2

google gsutil:ascii 编解码器无法编码字符