如何解决 UnicodeDecodeError?

Posted

技术标签:

【中文标题】如何解决 UnicodeDecodeError?【英文标题】:How to solve a UnicodeDecodeError? 【发布时间】:2012-02-05 14:07:59 【问题描述】:

我在尝试从数据存储区读取非 ascii 时收到一条奇怪的错误消息:

'ascii' codec can't decode byte 0xc3 in position 5: ordinal not in range(128)
Traceback (most recent call last):
  File "/base/data/home/apps/s~myapp-www/events.355951895377615944/webapp2.py", line 1511, in __call__
    rv = self.handle_exception(request, response, e)
  File "/base/data/home/apps/s~myapp-www/events.355951895377615944/webapp2.py", line 1505, in __call__
    rv = self.router.dispatch(request, response)
  File "/base/data/home/apps/s~myapp-www/events.355951895377615944/webapp2.py", line 1253, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/base/data/home/apps/s~myapp-www/events.355951895377615944/webapp2.py", line 1077, in __call__
    return handler.dispatch()
  File "/base/data/home/apps/s~myapp-www/events.355951895377615944/handler.py", line 127, in dispatch
    response = super(NewBaseHandler, self).dispatch()
  File "/base/data/home/apps/s~myapp-www/events.355951895377615944/webapp2.py", line 547, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/base/data/home/apps/s~myapp-www/events.355951895377615944/webapp2.py", line 545, in dispatch
    return method(*args, **kwargs)
  File "/base/data/home/apps/s~myapp-www/events.355951895377615944/handler.py", line 73, in check_login
    return handler(self, *args, **kwargs)
  File "/base/data/home/apps/s~myapp-www/events.355951895377615944/handler.py", line 526, in get
    user=user)
  File "/base/data/home/apps/s~myapp-www/events.355951895377615944/handler.py", line 91, in render_jinja
    **template_args))
  File "/base/data/home/apps/s~myapp-www/events.355951895377615944/webapp2_extras/jinja2.py", line 158, in render_template
    return self.environment.get_template(_filename).render(**context)
  File "/base/data/home/apps/s~myapp-www/events.355951895377615944/jinja2/environment.py", line 894, in render
    return self.environment.handle_exception(exc_info, True)
  File "template_files/my_organization.html", line 148, in top-level template code
    <li id=" person.key.id()|makeid " class="level_1 inactive   leaf"><a href="" style="" class=""><ins>&nbsp;</ins><table class="leaf_info"><tbody>    <tr><td class="name"> person.firstname   person.lastname person.key.id()|makeid</td><td class="level" title="New Distributor"><span class="level_parseable">1</span>1</td><td class="downlines">0</td><td class="cc_personal"><span class="cc_personal_parseable"></span>0</td><td class="cc_downlines"><span class="cc_downlines_parseable"></span>0</td><td class="cc_activity"><span class="cc_activity_parseable"></span>0</td><td class="cc_nonmanager"><span class="cc_nonmanager_parseable"></span>0</td><td class="cc_total"><span class="cc_total_parseable"></span>0</td></tr></tbody></table></a></li>% endfor %
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 5: ordinal not in range(128)

以前工作的循环很普通:

% for person in people %
    <li id=" person.key.id()|makeid " class="level_1 inactive   leaf">
<a href="" style="" class=""><ins>&nbsp;</ins><table class="leaf_info"><tbody>  <tr><td class="name"> person.firstname   person.lastname person.key.id()|makeid</td><td class="level" title="New Distributor"><span class="level_parseable">1</span>1</td><td class="downlines">0</td><td class="cc_personal"><span class="cc_personal_parseable"></span>0</td><td class="cc_downlines"><span class="cc_downlines_parseable"></span>0</td><td class="cc_activity"><span class="cc_activity_parseable"></span>0</td><td class="cc_nonmanager"><span class="cc_nonmanager_parseable"></span>0</td><td class="cc_total"><span class="cc_total_parseable"></span>0</td></tr></tbody></table></a></li>
% endfor %

我可以做些什么来解决这个错误?

我的处理程序看起来像这样

class Myorg(NewBaseHandler):
    @user_required
    def get(self):
        user = auth_models.User.get_by_id(long(self.auth.get_user_by_session()['user_id']))
        people = auth_models.User.query(auth_models.User.sponsor == user.key).fetch()
        self.render_jinja('my_organization.html', people=people,
                              user=user)

我的模型定义是来自 webapp2 的用户模型。这也是我的自定义文件管理器 makeid:

def makeid(n, countrycode="46"):
    countrycode = str(countrycode)
    n = str(n)
    return "%s%s%s" % (countrycode, '0'*(12-len(countrycode)-len(n)), n)

更新

解决方法很奇怪,我只是做了一个.decode('utf-8'),这不应该做:

class UpdateHandler(NewBaseHandler):

    @user_required
    def get(self):
        user = \
            auth_models.User.get_by_id(long(self.auth.get_user_by_session()['user_id'
                ]))
        sponsor = None
        if user.sponsor:
            sponsor = user.sponsor.get()
        address = None
        if user.address:
            address = user.address.decode('utf-8')
        if user.city:
            city = user.city.decode('utf-8')
        self.render_jinja('details.html', city=city, user=user, address=address, sponsor=sponsor, form=UpdateForm(obj=user))

有什么方法可以一次解码用户对象的所有变量,而不是一个一个地解码?

【问题讨论】:

查找包含 0xC3 或更一般的任何高位字符的数据库条目;和/或修复代码以接受您在数据库中的编码。 FWIW 0xC3 在 Latin-1 中是 Ã,如果你有的话,或者它可能是 UTF8 序列中的第一个字符。 我可以说我可能没有存储Ã。感谢您的评论,但我的代码应该处理来自数据存储区(谷歌应用引擎)的格式,除了模板之外几乎没有代码。由于错误仅发生在生产中,我还得出结论,它与从数据存储中读取的内容有关,即名为 people 的列表的内容,并且使用 python people = auth_models.User.query(auth_models.User.sponsor == user.key).fetch() 中的查询或多或少直接从数据存储中传递如果是 UTF8 序列会发生什么? 你能展示你模型的__unicode__方法吗?我怀疑那里有错误... 模型定义是来自 webapp2 的用户模型,即webapp-improved.appspot.com/api/webapp2_extras/appengine/auth/… 您能否也包含您的自定义过滤器“makeid”定义? 【参考方案1】:

您正在尝试将原始(字节)字符串插入 Unicode 模板。这是通过尝试使用某种编码(这里是默认的“ascii”编码)将原始字符串解码为 un​​icode 来完成的,因为它遇到了对 ASCII 无效的代码点。

要解决此问题,您只需将 unicode 字符串传递到模板中 - 在传递之前使用正确的编解码器对字符串进行解码。

【讨论】:

我将处理程序代码添加到问题中,并传递了一个在模板中迭代的实体列表。我似乎能够做的一件事是访问在迭代期间打印的字符串,并以某种方式转换到我刚刚输出 person.firstname 的位置,迭代查询的结果。 @NickRosencrantz 你能把你的模型定义也包括进来吗?如果您使用的是 StringProperty,则字符串应该已经是 Unicode。另外,您能否尝试将有问题的模板行拆分为多行,以便我们可以准确地看到哪个属性给您带来了问题?最后,它不是演员表——它是解码。不同的是解码需要编解码器。 感谢您的信息。模型定义是来自 webapp2 webapp-improved.appspot.com/api/webapp2_extras/appengine/auth/… 的 User 模型【参考方案2】:

最好的方法是将字符串转换为 ASCII 字符集。您可以使用 python encode cgi 函数转换为 ASCII

s = string_1.encode("ascii", "ignore")

Example

【讨论】:

【参考方案3】:

将您传递给模板的文本/HTML 转换为 Unicode,您应该会看到它消失了。之前在使用 webapp2 的 GAE 中使用 Django 模板时遇到过这个问题。

【讨论】:

以上是关于如何解决 UnicodeDecodeError?的主要内容,如果未能解决你的问题,请参考以下文章

使用configparser读取带有中文的配置文件出现UnicodeDecodeError错误

解决问题解决python安装模块时UnicodeDecodeError

当我在 python 中加载数据帧时出现 UnicodeDecodeError [重复]

使用Python解决Cx_Oracle查询时UnicodeDecodeError的问题

对于python中出现UnicodeDecodeError问题的解决方案

在多线程程序中添加 time.sleep 解决了 python 中的 UnicodeDecodeError