Unicode — Werkzeug 文档

来自菜鸟教程
Werkzeug/docs/1.0.x/unicode
跳转至:导航、​搜索

统一码

由于早期的 Python 2 天 unicode 是所有默认 Python 构建的一部分。 它允许开发人员以简单的方式编写处理非 ASCII 字符的应用程序。 但是使用 unicode 需要有关该问题的基本知识,尤其是在使用不支持它的库时。

Werkzeug 在所有假定文本数据的地方内部都使用 unicode,即使 HTTP 标准不像它那样识别 unicode。 基本上所有传入的数据都是从指定的字符集(默认为 utf-8)解码的,这样您就不再对字节串进行操作。 传出的 unicode 数据然后再次编码到目标字符集中。

Python 中的 Unicode

在 Python 2 中有两种基本的字符串类型:str 和 unicode。 str 可以携带编码的 unicode 数据,但它总是以字节表示,而 unicode 类型不包含字节而是字符点。 这是什么意思? 假设您有德语元音变音 ö。 在 ASCII 中你不能表示那个字符,但在 latin-1 和 utf-8 字符集中你可以表示它,但它们在编码时看起来不同:

>>> u'ö'.encode('latin1')
'\xf6'
>>> u'ö'.encode('utf-8')
'\xc3\xb6'

所以 ö 可能看起来完全不同,这取决于编码,这使得它很难使用。 解决方案是使用 unicode 类型(正如我们上面所做的,注意字符串前的 u 前缀)。 unicode 类型不存储 ö 的字节,而是存储信息,即这是 LATIN SMALL LETTER O WITH DIAERESIS

执行 len(u'ö') 将始终为我们提供预期的“1”,但 len('ö') 可能会根据 'ö' 的编码给出不同的结果。


HTTP 中的 Unicode

unicode 的问题在于 HTTP 不知道 unicode 是什么。 HTTP 仅限于字节,但这不是大问题,因为 Werkzeug 会自动为我们解码和编码所有传入和传出的数据。 基本上这意味着从浏览器发送到 Web 应用程序的数据默认从 utf-8 字节字符串解码为 unicode 字符串。 从应用程序发送回浏览器的还不是字节串的数据然后被编码回 utf-8。

通常这“有效”,我们不必担心,但在某些情况下,这种行为是有问题的。 例如,Python 2 IO 层不支持 unicode。 这意味着每当您处理来自文件系统的数据时,您都必须对其进行正确解码。 从文件系统加载文本文件的正确方法如下所示:

f = file('/path/to/the_file.txt', 'r')
try:
    text = f.decode('utf-8')    # assuming the file is utf-8 encoded
finally:
    f.close()

还有 codecs 模块,它提供了一个开放的功能,可以从给定的编码中自动解码。


错误处理

执行内部编码或解码的函数接受传递给 str.decode()str.encode()errors 关键字参数。 默认值为 'replace',以便于发现错误。 将其设置为 'strict' 以捕获错误并向客户端报告错误数据可能很有用。


请求和响应对象

由于请求和响应对象通常是 Werkzeug 驱动的应用程序的中心实体,您可以通过对这两个类进行子类化来更改 Werkzeug 操作的默认编码。 例如,您可以轻松地将应用程序设置为 utf-7 和严格的错误处理:

from werkzeug.wrappers import BaseRequest, BaseResponse

class Request(BaseRequest):
    charset = 'utf-7'
    encoding_errors = 'strict'

class Response(BaseResponse):
    charset = 'utf-7'

请记住,错误处理只能针对所有解码进行自定义,而不能针对编码进行自定义。 如果 Werkzeug 遇到编码错误,它将引发 UnicodeEncodeError。 您有责任不创建目标字符集中不存在的数据(所有 unicode 编码都没有问题,例如 utf-8)。


文件系统

在 0.11 版中更改。


在 0.11 版本之前,Werkzeug 使用 Python 的 stdlib 功能来检测文件系统编码。 但是,针对 Werkzeug 的几个错误报告表明,在传统 UNIX 系统下不能信任 sys.getfilesystemencoding() 的值。 通常的问题来自配置错误的系统,其中未设置 LANG 和类似的环境变量。 在这种情况下,Python 将默认使用 ASCII 作为文件系统编码,这是一个非常保守的默认值,通常是错误的,并且会导致比它避免的更多的问题。

因此,Werkzeug 将强制文件系统编码为 UTF-8 并在检测到它在 BSD 或 Linux 下运行时发出警告,并且 sys.getfilesystemencoding() 返回 ASCII 编码。

另见 werkzeug.filesystem