您的位置:首页 > 编程语言 > Python开发

python2 中文编码问题

2016-12-06 10:51 155 查看
在python代码中,写入中文是经常出现乱码和错误。

============知识背景============

1、首先看一下系统默认编码

就是说系统默认编码形式为ascii。

2、现在了解一下ASCII和非ASCII编码

在计算机内部,所有的信息最终都表示为一个二进制的字符串。每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码,一直沿用至今。ASCII码一共规定了128个字符的编码。

英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。于是出现用更多字节编码比如:简体中文常见的编码方式是GB2312,使用两个字节表示一个汉字,所以理论上最多可以表示256x256=65536个符号。这些属于非ASCII编码。

3、unicode

正如上一节所说,世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。unicode编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码。

但是,需要注意的是,unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。这样带来的问题就是,计算机不知道编码是unicode还是ascii。随后unicode出现了多种储存方式。

4、utf-8

UTF-8就是在互联网上使用最广的一种unicode的实现方式。其他实现方式还包括UTF-16和UTF-32,不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。

utf-8和unicode可以互相转化,比如:汉字“严”的Unicode码是4
4000
E25(100111000100101),UTF-8编码是E4B8A5(11100100
10111000 10100101)。

在windows下,最简单的转化方式是记事本。用记事本打开文件,文件》另存为,最下边“编码”可以改变编码存储方式:

其中:

1)ANSI是默认的编码方式。对于英文文件是ASCII编码,对于简体中文文件是GB2312编码。

2)Unicode编码指的是UCS-2编码方式,即直接用两个字节存入字符的Unicode码。这个选项用的little endian格式。

3)Unicode big endian编码与上一个选项相对应。我在下一节会解释little endian和big endian的涵义。

4)UTF-8编码,也就是上一节谈到的编码方法。

============python编码============

python内部是unicode编码,也就是说通常情况下,python用unicode作为转换中间量,decode作用为将其他编码字符串转换为unicode,接着encode将unicode编码转换为其他编码。一段例子:# -*- coding: utf-8 -*-

s="你好"# 整个文件是UTF-8编码,所以这里的字符串也是UTF-8
u=s.decode("utf-8") # 将utf-8的str转换为unicode
g=u.encode('gbk') # 将unicode转换为str,编码为GBK
print type(s),"len=",len(s) # 输出:<type ‘str‘> len= 6,utf-8每个汉字占3字节
print type(u),"len=",len(u) # 输出:<type ‘str‘> len= 6,unicode统计的是字数
print type(g),"len=",len(g) # 输出:g = u.encode(‘GBK‘),GBK每个汉字占2字节
print s # 在GBK/ANSI环境下(如Windows),输出乱码,#因为此时屏幕输出会被强制理解为GBK;
print g # 在Windows下输出“你好”

ss = '下午'.decode('utf-8')
print ss
print type(ss)

输出为:

这样,我们可以看到,字符串utf-8和unic的相互转化和内部存储编码。

============总结============

总结:

unicode是支持所有文字的统一编码,但一般只用作文字的内部表示,文件、网页(也是文件)、屏幕输入输出等处均需使用具体的外在编码,如GBK、UTF-8等;

encode和decode都是针对unicode进行“编码”和“解码”,所以encode是unicode->str的过程,decode是str->unicode的过程;

unicode和str是一对孪生兄弟,来自basestring,所以用isinstance(s, basestring)来判断s是否为字符串。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息