Python源代码文件的文本编码

源代码的编码问题对于任何语言的源文件都是存在的,只不过对于脚本语言,这个问题更突出一些。

有的人可能会说,既然源代码在文本编辑器中可以正常显示,说明编码没有问题,编辑器可以识别它,为什么Python还要求声明源代码的编码呢?

这是因为,明确地声明编码可以简化Python解释器的实现,免得它去猜测源文件的编码,这样既会增加解释器的复杂性,也会减慢程序的执行速度(毕竟是解释执行)。况且,程序运行必须是精确的,不能靠猜测。

从Python 2.3开始,可以在Python源文件中明确地声明字符编码,默认是7-bit ASCII编码。

字符编码声明是以在源文件第一行或者第二行出现的一个魔法注释来实现的:

# coding=<encoding name>

至于为什么必须是第一行或者第二行,这个很好解释:既然要解释一个文件,必须在最开始的时候就知道字符编码,但是在Unix/Linux平台上,第一行可能留给了Python解释器声明,#!/usr/bin/python,这也是一个魔法注释。

如果声明的编码Python解释器不认识,那么在编译阶段(对于CPython,这就是指将py文件转换成pyc文件)就会报错。

如果声明的编码与实际不符(就是说,文件实际上是以另外的编码保存的),出错的可能性很大,但是并非一定会出错,毕竟编码之间可能有一定的重叠。

如果没有声明源文件的编码,但是却使用了7-bit ASCII之外的字符,那么在编译(对于CPython,这就是指将py文件转换成pyc文件)的时候会出错,并且显示SyntaxError。

非7-bit ASCII字符大部分出现在字符串字面常量中,一些人会认为使用unicode字符串字面常量会解决编码的问题,但这完全是另一个层面上的问题,如果源文件的编码没有弄对,根本还到不了讨论unicode字符串那一步。

对于Windows平台而言,如果源文件是以utf-8格式存储的,它会在文件的开头加上BOM(Byte Order Mark),对于utf-8,这就是\xef\xbb\xbf,此时,无需对文件编码进行声明,如果要声明的话,也必须是utf-8,否则编译出错。

交互式输入窗口是有源文件编码的,允许输入中文,显然不是ascii。

Windows和Unix/Linux的换行符序列不相同,有的时候这也可能导致问题。

总之,如果编码有问题,编译时就会出错,如果运行时输出乱码,那应该是没有使用unicode字符串或者输出窗口不支持的缘故。

参考文档:

http://www.python.org/dev/peps/pep-0263/

http://bugs.python.org/issue526840

这两个文档描述了一些实现相关的细节,值得一看。

原文地址:https://www.cnblogs.com/frydsh/p/2592882.html