Python UnicodeDecodeError的最佳实践

5 投票
2 回答
1794 浏览
提问于 2025-04-16 05:29

我在用Pylons框架和Mako模板做一个网页应用。其实我之前并没有深入了解Python是怎么处理Unicode字符串的。有一次我看到我的网站崩溃了,页面渲染的时候出错,后来才知道是因为UnicodeDecodeError的问题。

看到这个错误后,我开始在我的Python代码里加上编码和解码的调用,使用'ignore'选项来忽略错误,但有时候错误还是没有消失。

最后,我用'ignore'选项把字符串解码成ascii,这样网站就能正常运行了,没有崩溃。

我的网站接收来自很多其他网站的输入。这意味着我无法控制输入的语言或用户的选择。我支持多种国际语言,还有英语。我有一个信息聚合功能,通常不太关注unicode、ascii或utf-8的问题。当我通过Mako模板显示文本时,我就直接显示原样的内容。

我不是网络专家,在Python项目中处理字符串有哪些最佳实践呢?我应该只在显示文本的时候注意,还是在应用的所有阶段都要关注这个问题?

2 个回答

2

这可能对你来说不是一个可行的选择,但我想说的是,很多与编码相关的错误在使用Python 3时会消失,因为它对Unicode字符串和字节对象的区分变得更加清晰。当我不得不使用Python 2时,我会选择2.6版本,在这个版本中你可以声明 from future import unicode_literals。不相信的人可以看看你发的链接,它指出了Python在编码和解码时的一些细微差别,而这些问题在Python 3中幸运地消失了。

你说

我无法控制语言或选择的语言。我的网站支持多种国际语言,还有英语。我有一个信息聚合功能,通常不关心unicode/ascii/utf-8。

无论你选择做什么,很明显你不想让你的网页应用因为某个丹麦博主的文章使用了一个不常见的斯堪的纳维亚编码而崩溃。这个根本问题对所有网页应用都很重要,因为网址并不携带编码信息,而且你永远不知道恶意用户可能会发送给你什么字节序列。在这种情况下,我会做我称之为“安全链解码”的操作:我先尝试用utf-8解码,如果失败了,再尝试用cp1252解码。如果这也失败了,我就丢弃这个请求(返回HTTP 404)或者做其他类似的处理。

你提到你处理信息流,而你呢?这些信息流?并不“关心”unicode和编码。你能解释一下这句话吗?我完全无法理解怎么能成功建立一个支持多种语言文本的网站,而不去关注编码。显然,仅使用ascii是无法走得很远的。

11

如果你能控制这个问题,下面是一个简单的方法:

  • 首先要知道你的输入编码是什么(或者可以选择忽略一些错误),然后在数据进入你的应用时,立刻用 decode(encoding) 来解码这些数据。
  • 在内部处理时,尽量只使用unicode(比如 u'something' 就是unicode),包括在数据库中也是如此。
  • 当数据需要输出、渲染或者离开你的应用时,使用 encode('utf-8') 来编码这些数据。

撰写回答