【问题标题】:How to properly handle non ASCII strings in python如何在python中正确处理非ASCII字符串
【发布时间】:2012-10-03 03:01:20
【问题描述】:

我正在构建一个应用程序,该应用程序在数据库中包含带有拉丁符号的数据。用户可以输入这些数据。 到目前为止,我一直在做的是在模板中显示数据时在最后对每个用户输入进行编码('latin2')和解码('latin2')。 这有点烦人,我想知道是否有更好的方法来处理这个问题。

【问题讨论】:

  • 通常您希望将数据存储为 unicode 并在输入/输出点与 unicode 进行转换。 user_input --> decode --> unicode --> encode --> user_output.
  • 你是什么意思“后端有拉丁符号的数据”?这些数据是否在数据库中?
  • @monkut 那么我是否应该确保数据库中的数据以 unicode 格式存储?
  • “剩下的唯一问题是数据还包含像


    标签这样的 html 标记,它们会被解码并显示为文本的一部分。”你用的是什么网络框架?

  • 更新了我的答案,解释了一些关于转义标记的内容(Flask 上的绝佳选择,顺便说一句!)

标签: python python-unicode


【解决方案1】:

Python 的unicode 类型被设计为字符串的“自然”表示。除了unicode 类型之外,字符串应该是一些未指定的编码,但是没有办法用使用的编码“标记”它们,python 会非常坚持地假设字符串是 ASCII 或 UTF-8 编码。因此,如果您编写整个程序以假设str 表示拉丁语2,您可能会感到头疼。编码问题会潜入代码中的奇怪位置并渗透到各个层,有时会在数据库中获取错误数据,并最终在完全不相关且无法调试的地方导致奇怪的行为或严重错误。

我建议您了解如何将您的数据库数据转换为 UTF-8。

如果您不能这样做,我强烈建议您将编码/解码调用移动到您向/从数据库传输数据的那一刻。如果您有任何类型的数据库抽象层,您可能可以将其配置为或多或少地自动为您处理。然后,您应该确保所有用户输入都立即转换为 unicode 类型。

使用unicode 类型并以这种方式显式编码/解码还有一个优点,即如果您确实遇到编码问题,您可能会很快注意到,您可以将unicode-nazi 扔给他们以追踪它们(参见@987654322 @)。


对于您的标记问题:Flask 和 Jinja2 默认情况下会在将字符串中的任何不安全字符呈现到 HTML 之前对其进行转义。要覆盖自动转义,只需使用 safe 过滤器:
<h1>More than just text!</h1>
<div>{{ html_data|safe }}</div>

有关详细信息,请参阅Flask Templates: Controlling Autoescaping,并极其谨慎地使用它,因为您正在有效地从数据库加载代码并执行它。在现实生活中,您可能想要清理数据(请参阅 Python HTML sanitizer / scrubber / filterJinja2 escape all HTML but img, b, etc)。

【讨论】:

【解决方案2】:

尝试将此添加到程序的顶部。

 import sys
 reload(sys)
 sys.setdefaultencoding('latin2')

我们必须重新加载系统,因为:

>>> import sys
>>> sys.setdefaultencoding
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'setdefaultencoding'
>>> reload(sys) 
<module 'sys' (built-in)>
>>> sys.setdefaultencoding
<built-in function setdefaultencoding>

【讨论】:

  • 发现此演示文稿作者不推荐使用 setdefaultencoding() - farmdev.com/talks/unicode
  • 该演示文稿警告说,设置默认编码可能会破坏某些第三方模块,这取决于您在做什么,这可能不是什么大问题。
猜你喜欢
  • 2013-03-22
  • 2010-11-23
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 2013-07-13
  • 1970-01-01
  • 1970-01-01
  • 2019-05-21
相关资源
最近更新 更多