[python] python3字符编码问题

  对于一个python初学者,想必被python中文编码时的各种出错苦苦折磨一番是一条必由之路。对于python编译器文件编码,python字符文本编码,操作系统(命令行)编码,各文本编辑器的编码,如果没有准确理解各个编码的意思,这里面可谓是一路的坑。

ASCII:是基于拉丁字母的一套电脑编码系统,主要用于显示英语,一个字符用1个字节(8bit)表示。不能显示汉字字符。

GBK:是针对汉字的编码规范。1995年制定,收录约21000个字符,一个字符用2个字节(16bit)表示。一般windows中文操作系统默认的就是gbk编码方式,是微软的标准,GBK 向下与 GB 2312 编码兼容。

Unicode:万国码,支持所有国家和地区的编码,统一一个字符用4个字节(32bit)表示,向下兼容ASCII、GBK、GB2312等编码。

UTF-8:可变长的字符编码集,是unicode的扩展集。在UTF-8中对于ASCII码的英文字符用1个字节表示,欧洲字符用2个字节表示,东亚字符用3个字节表示,更加优化。

ASNI:纯文本txt的默认保存方式。它并不是某一种特定的字符编码,而是在不同的系统中,ANSI表示不同的编码。在windows英文系统中ANSI编码其实是ASCII编码(ASCII编码不能表示汉字,所以汉字为乱码),而windows中文系统中ANSI编码其实是GBK编码,在windows韩文系统中ANSI编码其实是EUC-KR编码。

  将下面代码分别用纯文本txt、Geany编译器、pycharm编译器编写保存。

name1 = "北京"
name2 = name1 
print(name1,name2)
name1 = "南京"
print(name1,name2)

  在执行时,只有在pycharm中可以正确运行,其他两种均报错如下:

SyntaxError: Non-UTF-8 code starting with '\xb1' in file demo.txt on line 1, butno encoding declared; 

  在纯文本txt文件中代码默认保存方式为ASNI编码,而在windows中文操作系统中ASNI编码就是GBK编码,这时采用2个字节(16bit)保存一个字符。这样程序文件就以GBK方式被保存下来,而python3中默认文件编码是UTF-8,默认字符文本的格式为unicode。python在执行时识别该文件格式并不是UTF-8,所以就报错了。如果将程序代码txt文件另存为如下图的UTF-8编码格式,再次执行时代码文件格式与python3默认文件格式一致,就不会报错了。同时在命令行也可以正确显示中文字符了,这是因为python3中默认字符文本格式为unicode,windows中文操作系统中的命令行默认编码是ANSI,也就是GBK(命令行右击属性里查看),unicode可以兼容GBK,所以即使不用编码和解码也可以正确显示。

  在Geany编辑器首选项中默认缺省文件格式为GBK编码格式(如下图)。可以将这一项修改为UTF-8后,即可正确执行该代码。在pycharm中默认文件编码格式就是UTF-8格式,所以你怎么玩都不会出错。

  另外值得一提的就是在内存中字符都是以unicode形式编码的,譬如说当我们新建一个txt来保存纯文本时,当我们在其中任意输入一个汉字字符时,首先是写入到内存中去的,这一步就是将操作系统中的汉字GBK编码转换成了unicode编码写入内存的,当我们单击默认形式保存时,此时内存中的unicode编码形式的汉字又被转换成GBK编码存储到磁盘中去的。举个例子来说,我们新建一个hello.txt文本以默认方式保存,并在其中写入“你好啊,欢迎您!”8个汉字字符,在命令行运行下面程序:

f = open(r'D:\hello.txt','r')
print(f.tell())
>>>0
print(f.read(2))
>>>你好
print(f.tell())
>>>4

  第一次用f.tell()打印出来程序开始时磁盘文件中字符的指针默认开始处,当我们读取2个汉字字符后,文件指针指向就向后移动了2个汉字字符,因为在GBK中汉字字符默认2个字节,所以指针指向了4,再次打印f.tell()后显示的也是4。可见文件在磁盘中是以GBK编码保存的。

posted @ 2018-02-28 22:52  自由天空远走高飞  阅读(480)  评论(0编辑  收藏  举报