Flask中的Unicode

Flask 与 Jinja2 、Werkzeug 一样,在文本方面完全基于Unicode。不仅是这些库,还有处理文本的大多数与Web相关的Python库都是这样处理文本的。如果到目前为止你还不知道Unicode,最好先阅读软件开发人员 Unicode 和 字符集应知应会 。本文档尝试介绍一些基本的知识,以便于能够愉快地处理与 Unicode 相关的问题.

自动转换

为了提供基本的、无痛的Unicode 支持, Flask对你的应用程序(当然可以更改) 做了以下假设:

  • 你网站上的文本编码是UTF-8
  • 在内部,除了只有ASCII字符的文本字符串外,在内部对文本始终只使用Unicode.
  • 只要通过协议传送字节,都离不开编码和解码过程.

所以,这对你来说有什么意义?

HTTP基于字节的,不仅是协议,还包括用于定位服务器上文档的系统(所谓的URI或URL)。然而,通常在HTTP上传送的HTML支持各种各样的字符集,并且需要在 HTTP header 中注明。为了避免这个问题过于复杂,flask假设你发送的都是 UTF-8 编码的 Unicode,Flask会为你完成编码工作,并设置适当的 header.

如果你使用sqlacalchemy或类似的ORM系统操作数据库,道理也是同样的。一些数据库已经使用传输 Unicode的协议,即使没有,SQLALchemy 或其它ORM 也会自动处理好这个问题.

黄金法则

所以经验法则是:如果不是处理二进制数据,那么一律使用Unicode。在python 2.x中,使用unicode意味着什么?

  • 只要你只使用ASCII字符点(基本上是数字,一些拉丁字母的特殊字符不带斜杠或任何花哨的字符),就可以使用常规字符串文字。( 'Hello World'
  • 如果在字符串中需要使用除ASCII以外的任何内容,则必须将此字符串标记为Unicode字符串,方法是在其前面加上小写字母 u作为前缀。(比如 u'Hänsel und Gretel'
  • 如果在python文件中使用非unicode字符,则必须告诉python使用了何种编码。为此,我再次推荐使用UTF-8。你可以在 Python源文件的第一行或第二行写入 # -- coding: utf-8 -- 来告知解释器你的编码类型.
  • Jinja被配置为以 UTF-8解码模板文件,所以一定要确保你的编辑器把文件保存为utf-8格式.

自助编码和解码

如果你打交道的文件系统或环境不是真正基于Unicode 编码的话,那么您必须确保在使用Unicode接口时正确解码。因此,例如,如果您想在文件系统上加载一个文件并将其嵌入到jinja2模板中,那么您必须按照该文件的编码中对其进行解码。在这里,文本文件不指定其本身编码的老问题开始出现。因此,请帮自己一个忙,限制自己在文本文件中使用UTF-8.

不管怎样。要用unicode加载这样的文件,可以使用内置的 str.decode() 方法:

def read_file(filename, charset='utf-8'):
    with open(filename, 'r') as f:
        return f.read().decode(charset)

要将Unicode转换为特定字符集(如UTF-8),可以使用 unicode.encode() 方法:

def write_file(filename, contents, charset='utf-8'):
    with open(filename, 'w') as f:
        f.write(contents.encode(charset))

配置编辑器

现在大多数编辑器默认保存为utf-8,但如果你的编辑器不是,则必须更改它。下面是设置一些编辑器存储为UTF-8的常见方法:

  • Vim: 在你的 .vimrc 文件中加入 set enc=utf-8.

  • Emacs:要么使用编码cookie,要么把这段文字加入到你的 .emacs 文件:

    (prefer-coding-system 'utf-8)
    (setq default-buffer-file-coding-system 'utf-8)
    
  • 记事本+ +:

    1. 打开 设置 -> 首选项*
    2. 选择“新建文档/缺省目录”选项卡
    3. 选择“无BOM的UTF-8”作为编码

    还建议使用unix换行格式,您可以在同一面板中选择它,但这不是必须的.