【问题标题】:Python : UnicodeEncodeError: 'latin-1' codec can't encode characterPython:UnicodeEncodeError:'latin-1'编解码器无法编码字符
【发布时间】:2012-01-07 13:54:18
【问题描述】:

我在调用 api 的情况下,根据 api 的结果,我为我在 api 中的每条记录调用数据库。我的 api 调用返回字符串,当我对 api 返回的项目进行数据库调用时,对于某些元素,我收到以下错误。

Traceback (most recent call last):
  File "TopLevelCategories.py", line 267, in <module>
    cursor.execute(categoryQuery, {'title': startCategory});
  File "/opt/ts/python/2.7/lib/python2.7/site-packages/MySQLdb/cursors.py", line 158, in execute
    query = query % db.literal(args)
  File "/opt/ts/python/2.7/lib/python2.7/site-packages/MySQLdb/connections.py", line 265, in literal
    return self.escape(o, self.encoders)
  File "/opt/ts/python/2.7/lib/python2.7/site-packages/MySQLdb/connections.py", line 203, in unicode_literal
    return db.literal(u.encode(unicode_literal.charset))
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2013' in position 3: ordinal not in range(256)

上述错误所指的代码段是:

         ...    
         for startCategory in value[0]:
            categoryResults = []
            try:
                categoryRow = ""
                baseCategoryTree[startCategory] = []
                #print categoryQuery % {'title': startCategory}; 
                cursor.execute(categoryQuery, {'title': startCategory}) #unicode issue
                done = False
                cont...

做了一些谷歌搜索后,我在命令行上尝试了以下操作以了解发生了什么......

>>> import sys
>>> u'\u2013'.encode('iso-8859-1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2013' in position 0: ordinal not in range(256)
>>> u'\u2013'.encode('cp1252')
'\x96'
>>> '\u2013'.encode('cp1252')
'\\u2013'
>>> u'\u2013'.encode('cp1252')
'\x96'

但我不确定解决此问题的方法是什么。另外我不知道encode('cp1252') 背后的理论是什么,如果我能对上面的尝试得到一些解释,那就太好了。

【问题讨论】:

标签: python unicode encode


【解决方案1】:

unicode 字符 u'\02013' 是“短划线”。它包含在 Windows-1252 (cp1252) 字符集中(编码为 x96),但不包含在 Latin-1 (iso-8859-1) 字符集中。 Windows-1252 字符集在 x80 - x9f 区域定义了更多字符,其中包括短划线。

解决方案是让您选择不同于 Latin-1 的目标字符集,例如 Windows-1252 或 UTF-8,或者将短破折号替换为简单的“-”。

【讨论】:

    【解决方案2】:

    u.encode('utf-8') 将其转换为字节,然后可以使用sys.stdout.buffer.write(bytes) 在标准输出上打印 检查显示挂钩 https://docs.python.org/3/library/sys.html

    【讨论】:

      【解决方案3】:

      如果您需要 Latin-1 编码,您有几个选项可以去掉破折号或其他 255 以上的代码点(Latin-1 中不包含的字符):

      >>> u = u'hello\u2013world'
      >>> u.encode('latin-1', 'replace')    # replace it with a question mark
      'hello?world'
      >>> u.encode('latin-1', 'ignore')     # ignore it
      'helloworld'
      

      或者做你自己的自定义替换:

      >>> u.replace(u'\u2013', '-').encode('latin-1')
      'hello-world'
      

      如果您不需要输出 Latin-1,那么 UTF-8 是一种常见且首选的选择。它是 W3C 推荐的,可以很好地编码所有 Unicode 代码点:

      >>> u.encode('utf-8')
      'hello\xe2\x80\x93world'
      

      【讨论】:

        猜你喜欢
        • 2011-04-25
        • 1970-01-01
        • 2015-04-08
        • 1970-01-01
        • 2018-12-11
        • 1970-01-01
        • 1970-01-01
        • 2019-12-09
        相关资源
        最近更新 更多