【问题标题】:Need help to figure out a solution to this UnicodeDecodeError需要帮助找出解决此 UnicodeDecodeError 的方法
【发布时间】:2012-08-17 00:12:45
【问题描述】:

当我使用此代码时(改编自 Stephen Holiday code - 感谢 Stephen 提供您的代码!):

#!/usr/bin/env python    
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-

"""
USSSALoader.py
"""
import os
import re
#import urllib2
from zipfile import ZipFile
import csv
import pickle

def getNameList():
    namesDict=extractNamesDict()
    maleNames=list()
    femaleNames=list()
    for name in namesDict:
        counts=namesDict[name]
        tuple=(name,counts[0],counts[1])
        if counts[0]>counts[1]:
            maleNames.append(tuple)
        elif counts[1]>counts[0]:
            femaleNames.append(tuple)
    names=(maleNames,femaleNames)
    return names

def extractNamesDict():
    zf=ZipFile('names.zip', 'r')
    filenames=zf.namelist()

    names=dict()
    genderMap={'M':0,'F':1}

    for filename in filenames:
        file=zf.open(filename,'r')
        rows=csv.reader(file, delimiter=',')

        for row in rows:
            name=row[0].upper()
           # name=row[0].upper().encode('utf-8')
            gender=genderMap[row[1]]
            count=int(row[2])

            if not names.has_key(name):
                names[name]=[0,0]
            names[name][gender]=names[name][gender]+count

        file.close()
        print '\tImported %s'%filename
    return names

if __name__ == "__main__":
    getNameList()

我收到了这个错误:

  iterator = raw_query.Run(**kwargs)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\api\datastore.py", line 1622, in Run
    itr = Iterator(self.GetBatcher(config=config))
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\api\datastore.py", line 1601, in GetBatcher
    return self.GetQuery().run(_GetConnection(), query_options)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\api\datastore.py", line 1490, in GetQuery
    filter_predicate=self.GetFilterPredicate(),
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\api\datastore.py", line 1534, in GetFilterPredicate
    property_filters.append(datastore_query.make_filter(name, op, values))
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\datastore\datastore_query.py", line 107, in make_filter
    properties = datastore_types.ToPropertyPb(name, values)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\api\datastore_types.py", line 1745, in ToPropertyPb
    pbvalue = pack_prop(name, v, pb.mutable_value())
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\api\datastore_types.py", line 1556, in PackString
    pbvalue.set_stringvalue(unicode(value).encode('utf-8'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe1 in position 1: ordinal not in range(128)

当我的名字包含非 ASCII 字符(如“Chávez”或“Barañao”)时会发生这种情况。我试图解决这个问题:

     for row in rows:
           # name=row[0].upper()
            name=row[0].upper().encode('utf-8')
            gender=genderMap[row[1]]
            count=int(row[2])

但是,然后,我得到了另一个错误:

 File "C:\Users\CG\Desktop\Google Drive\Sci&Tech\projects\naivebayes\USSSALoader.py", line 17, in getNameList
    namesDict=extractNamesDict()
  File "C:\Users\CG\Desktop\Google Drive\Sci&Tech\projects\naivebayes\USSSALoader.py", line 43, in extractNamesDict
    name=row[0].upper().encode('utf-8')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xed in position 3: ordinal not in range(128)

我也试过这个:

def extractNamesDict():
    zf=ZipFile('names.zip', 'r', encode='utf-8')
    filenames=zf.namelist()

但是ZipFile没有这样的论点。

那么,如何解决这个问题,避免 UnicodeDecodeError 用于非 ASCII 名称?

我正在将此代码与 GAE 一起使用。

【问题讨论】:

标签: python google-app-engine unicode utf-8 unicode-string


【解决方案1】:

您的第一个回溯似乎与 AppEngine 相关。您是否正在构建将填充数据存储的加载程序?如果是这样,查看包含模型的代码并执行put'ing 会很有帮助。我可能会被某人纠正,但为了让那部分工作我相信你实际上需要decode而不是encode(即当你在put之前阅读工作表时,将字符串转换为unicode使用decode('utf-8')decode('latin1'),取决于你的情况)。

就您的本地代码而言,我不会假装了解 Unicode 处理的深层内部原理,但我通常使用 decode()encode() 来处理这些类型的情况。我相信要使用的正确编码取决于底层文本(这意味着您需要知道它是编码为utf-8 还是latin-1 等)。这是您的示例的快速测试:

>>> s = 'Chávez'
>>> type(s)
<type 'str'>
>>> u = s.decode('latin1')
>>> type(u)
<type 'unicode'>
>>> e = u.encode('latin1')
>>> print e
Chávez

在这种情况下,我需要使用 latin1 来解码编码的字符串(我使用的是终端),但在您的情况下使用 utf-8 可能会很好。

【讨论】:

  • 坦克,@RocketDonkey。如果我尝试解码('utf-8'),我得到这个错误:C:\Python27\lib\encodings\utf_8.py 16 UnicodeDecodeError: 'utf8' codec can't decode byte 0xe3 in position 2: unexpected end of data 如果我尝试解码('latin1'),没有错误,但是从这个脚本返回名称并保存在我的数据库中(在其他脚本)这样:u'C\xe9SAR' 代替 u'César' 和 u'ANT\xc3\x94NIO' 代替 u'Antônio'。还有什么提示吗?
  • @Pythonista'sApprentice 你检查过输出时信息是什么样子的吗?例如,如果您要从数据存储中读取数据并将其打印到页面(或者您的应用程序处理它),它是否正确显示?我相信您只是看到数据存储如何在内部存储数据(作为 unicode),并且您应该能够输出数据并将其显示为 CésarAntônio(您可能需要执行 @987654338 @在打印前踩一下返回的数据)。
  • 谢谢,它几乎是完美的,有一些错误:Antônio 变成了Antânio。我会检查一下。
  • 很高兴听到!希望你能把它整理出来;如果没有,很乐意帮助解决问题。
  • 你的帮助是值得的!!在几乎所有情况下都运行良好!但现在我正在尝试删除重音符号,但收到此错误:stackoverflow.com/questions/12014810/… 再次感谢!
【解决方案2】:

除非我遗漏了什么,否则图书馆中的这一行:

pbvalue.set_stringvalue(unicode(value).encode('utf-8'))

应该是:

pbvalue.set_stringvalue(value.decode(filename_encoding).encode('utf-8'))

如果值filename_encoding 没有以某种方式存储在 zip 存档中(至少在该格式的早期版本中,我怀疑它是否被存储),则从您的代码中传入的值 filename_encoding。这是假设字节和“字符”是同一事物的经典错误的又一次出现。

如果您感到困惑,请深入研究代码并修复它,甚至可以贡献一个补丁。否则,您将不得不编写英雄代码来检查文件名中的 U+0080 及更高版本并执行特殊处理。

【讨论】:

    【解决方案3】:

    在 python 2.7(和 linux Mint 17.1)中,你必须使用: hashtags=['transito','transito','ñandú','pingüino','fhürer'] 用于标签中的 h: u=h.decode('utf-8') 打印(u.encode('utf-8'))

    过渡 过境 南杜 平圭诺 弗雷尔

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多