中文字符编码和pathon中文字符显示总结

来源:互联网 发布:淘宝介入后可以撤销吗 编辑:程序博客网 时间:2024/05/17 22:29

最近在学习python,遇到显示中文出现乱码的情况,在这里做个总结。

出现乱码就是因为字符的编码方式不同引起的,而要说到字符编码,首先需要说下文本文件:

文本文件:(中文wiki在这里)是指以ASCII码方式(也称文本方式)存储的文件,更确切地说,英文、数字等字符存储的是ASCII码(由ANSI发布,标准ASCII为128个,后来被扩展为256个),而汉字存储的是机内码

其实文本文件里面放的也是0和1组成的二进制数,只是像a、b、c这样的字母存放的是0x61、0x62、0x63,而对于汉字,在存放的是其对应的2个字节的编码,而中文编码方式又有:GB2312(1981年发布)、GBK(1993年发布)和GB18030(2000年第一次发布),这3中编码是向后兼容的,也就是说,GB2312里面的汉字GBK里面也含有,GBK里面的汉字GB18030也一定含有,而且是一样的编码。这里我们来说一下所谓的“编码”,其实就是由国家的标准委员会为我们使用的每个汉字取一个编号,就像我们每个人都有一个唯一的身份证号吗一样,这样就可以在计算机里面唯一的表示一个汉字。可以到网上下载一个常用汉字的机内码来参照一下(百度文库的链接)。

而世界上又有许许多多的语言和对应的文字,为了大家能够更好的进行交流,国际组织就对每个国家的文字进行统一的编码,每种文字里面的每个字符都对应一个唯一的编号,这就是Unicode编码(中文wiki在这里),unicode一般使用的是二个字节来进行编码的,也就是说汉字和英文都是的是两个字节(百度文库的链接)。但是对于老外来说他们使用比较多的是英文字母和标点,而英文的ACSII只需要一个字节来表示就够了,本着不浪费的精神,老外又发明了utf-8这个unicode编码的实现方式(中文wili在这里),在utf-8里面,英文还是一个字节就可以表示够了的,但是中文却需要3个字节来表示。在这里简单介绍一个中文utf-8的二进制数与unicode编码的转换方法:

首先说下utf-8编码的方法:

1、utf-8的第一个字节的前面几个位为1表示这个编码里面总共有几个字节,如1100xxxxx,表示有2个字节,1110xxxx表示有3个字节。
2、其他字节的前面两位必须是10,如10xxxxxx (x为任意的0或者1)


比如“中”字:
GBK编码的机内码,使用十六进制表示为:D6D0
Unicode有自己的对应表,使用十六进制表示为:\u4e2d
而utf-8,采用3个字节,使用十六进制表示为:E4B8AD


4e2d 对应的二进制数为:1001110 00101101,这个是“中”的unicode编码的值。
把最后面的6位分出来加上10组成一个字节:10101101==0xAD(非第一个字节的前面两位为10)
剩下1001110 00的后面6位分出来,加上10组成一个字节:10111000==0xB8
最后剩下100,由于总共含有3个字节所以为:11100100==0xE4。(第一个字节的前面几位含有几个1表示总共含有几个字节,这里总共有3个字节,所以为1110
有高位到地位组合起来就是11100100  10111000  10101101,也就是0xE4B8AD,这个是“中”的utf-8编码的二进制数。(把有蓝色背景的0和1去掉就变为了:

0100 1110 0010 1101,就是0x4e2d,也就是“中“的unicode编码值


python里面包含两种字符串:str对象的字符串和unicode对象的字符串

其中对于str对象的字符串我们可以选择汉字的编码方式,比如汉字“中”,当我们选择编码方式为gbk的时候,在源文件里面对应的就是0xD6D0,这个可以通过UltraEdit或者NotePad++等可以查看16进制的编辑器来查看,而当我们使用utf-8编码的时候,在源文件里面对应的就是0xE4B8AD。

在python的windows下集成开发环境IDLE中通过

#-*- coding: utf-8 -*-
就可以设置源文件的编码方式为utf-8了。

当python的解释器在源文件中读取到0xE4B8AD这个数据的时候,它就能知道代表的是“中”这个汉字字符了。

通过python的IDEL来运行下面这段代码

#-*- coding: utf-8 -*-s="中国"print s

结果为

>>> 
中国
>>> 

但是如果通过cmd窗口来运行,则会出现


这个是因为我们使用的cmd窗口默认的是gbk的汉字编码,当我们把“中国”对应的utf-8的二进制流0xE4B8AD和0xE59BBD(由于我们源文件的编码方式为utf-8)传给cmd窗口进行输出的时候,cmd窗口把这个二进制流当成了0xxE4B8、0xADE5和0x9BBD的GBK编码,其对应的就是“涓”和后面两个字符了。

要想解决这个问题可以使用unicode对象,unicode对象有两个方法encode和decode,encode是把unicode对象转换为某种编码方式的str对象,而decode是把某种编码方式的str对象转换为unicode对象,

我们把源代码改为:

#-*- coding: utf-8 -*-s="中国"print s.decode("utf-8")
结果为:

>>> 
中国
>>> 


这个是由于cmd窗口支持unicode的输出。

我们在修改一下源代码:

#-*- coding: utf-8 -*-s="中国"print s.decode("utf-8").encode("gbk")

结果为:

>>> 
中国
>>> 


在这里我们先把utf-8编码的字符串转为unicode对象,然后转换为gbk编码的str对象,然后在使用print进行输出,因为cmd窗口使用的是gbk编码,所以输出的时候ok。


在这里有两点要搞清楚:

1、源文件,也就是文本文件也是有编码方式的,我们一般默认是使用的ANSI编码,英文使用ASCII字符编码,中文使用GBK编码的汉字机内码。在python中使用

#-*- coding: gbk -*-
即可使用gbk编码汉字。2、python里面有两种字符串,str对象和uniocde对象,可以通过unicode对象的encode和decode方法进行转换。而python默认使用的是ASCII字符编码,所以如果使用汉字的时候,如果没有显示的说使用编码方式,解释器会报错的,因为它使用ASCII编码。而ASCII编码里面最高位为0,不会包含像0xD6D0这样的数据,解释器当然不认识他们,只能报错了。

原创粉丝点击