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

如何在python中正确处理非ASCII字符串,python,python-unicode,Python,Python Unicode,我正在构建一个应用程序,在数据库中有带有拉丁符号的数据。用户可以输入此数据。 到目前为止,我一直在做的是在模板中显示数据时,对每个用户输入的数据进行编码('latin2'),并在最后对其进行解码('latin2')。 这有点烦人,我想知道是否有更好的方法来处理这个问题。尝试将它添加到程序顶部 import sys reload(sys) sys.setdefaultencoding('latin2') 我们必须重新加载sys,因为: >>> import sys >

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

尝试将它添加到程序顶部

 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>
导入系统 >>>sys.setdefaultencoding 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 AttributeError:“模块”对象没有属性“setdefaultencoding” >>>重新加载(系统) >>>sys.setdefaultencoding
尝试将其添加到程序顶部

 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>
导入系统 >>>sys.setdefaultencoding 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 AttributeError:“模块”对象没有属性“setdefaultencoding” >>>重新加载(系统) >>>sys.setdefaultencoding
Python的
unicode
类型被设计为字符串的“自然”表示形式。除了
unicode
类型之外,字符串还应该使用一些未指定的编码,但是无法使用所使用的编码对其进行“标记”,python将非常坚持地假设字符串是ASCII或UTF-8编码。因此,如果您编写整个程序时假设
str
表示拉丁语2,那么您可能会感到头疼。编码问题会在代码中的一些奇怪的地方潜入,并渗透到各个层中,有时会在数据库中获取坏数据,最终会在完全无关且无法调试的地方导致奇怪的行为或严重的错误

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

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

使用
unicode
类型并以这种方式显式编码/解码还有一个好处,即如果您确实存在编码问题,您可能会很快注意到,您可以直接使用它们来跟踪它们(请参阅)


对于标记问题:Flask和Jinja2在默认情况下会在将字符串中的任何不安全字符呈现到HTML之前转义它们。要覆盖自动转义,只需使用
safe
过滤器:

<h1>More than just text!</h1>
<div>{{ html_data|safe }}</div>
不仅仅是文本!
{{html_data | safe}}

有关详细信息,请参阅,并非常小心地使用此选项,因为您正在从数据库有效地加载代码并执行它。在现实生活中,您可能需要清理数据(请参见或)。

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

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

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

使用
unicode
类型并以这种方式显式编码/解码还有一个好处,即如果您确实存在编码问题,您可能会很快注意到,您可以直接使用它们来跟踪它们(请参阅)


对于标记问题:Flask和Jinja2在默认情况下会在将字符串中的任何不安全字符呈现到HTML之前转义它们。要覆盖自动转义,只需使用
safe
过滤器:

<h1>More than just text!</h1>
<div>{{ html_data|safe }}</div>
不仅仅是文本!
{{html_data | safe}}

有关详细信息,请参阅,并非常小心地使用此选项,因为您正在从数据库有效地加载代码并执行它。在现实生活中,您可能需要清除数据(请参见或)。

通常,您希望将数据存储为unicode,并在输入/输出点与unicode进行转换。用户输入-->解码-->unicode-->编码-->用户输出。您说“后端有带拉丁符号的数据”是什么意思?这是数据库中的数据吗?@monkut然后我应该确保数据库中的数据以unicode格式存储吗?“剩下的唯一问题是,数据还包含html标记,如和
标记,这些标记被解码并显示为文本的一部分。”您使用的是什么web框架?更新了我的回答,解释了一些关于转义标记的内容(顺便说一句,Flask上的最佳选择!)通常您希望将数据存储为unicode,并在输入/输出点与unicode进行转换。用户\u输入-->解码-->unicode-->编码-->用户\u输出。您认为“后端有带拉丁符号的数据”是什么意思?这是数据库中的数据吗?@monkut然后我应该确保数据库中的数据以unicode格式存储吗?“剩下的唯一问题是,数据还包含html标记,如和
标记,这些标记被解码并显示为文本的一部分。”您使用的是什么web框架?更新了我的回答,解释了一些关于转义标记的内容(顺便说一句,烧瓶是不错的选择!)找到了这个演示文稿