如何在python中正确处理非ASCII字符串

时间:2012-10-03 03:01:20

标签: python python-unicode

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

2 个答案:

答案 0 :(得分:2)

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

我建议你看看有关将数据转换为UTF-8的信息。

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

使用unicode类型并以这种方式显式编码/解码也具有以下优势:如果您遇到编码问题,您可能会更快注意到,您可以向它们抛出unicode-nazi来跟踪它们(见How can you make python 2.x warn when coercing strings to unicode?)。

<小时/> 对于标记问题:Flask和Jinja2默认会将字符串中的任何不安全字符转义为HTML,然后再将其转换为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)。

答案 1 :(得分:1)

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

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

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

>>> 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>