encode / decode
编码 unicode utf-8 gb2312
__update_____________________________________________________________
最早的Python只支持ASCII编码,
普通的字符串'ABC'在Python内部都是ASCII编码的。
Python在后来添加了对Unicode的支持,以Unicode表示的字符串用u'...'表示,
eg. s= u'中文'
u'中'和u'\u4e2d'是一样的,\u后面是十六进制的Unicode码。
u'A'和u'\u0041'也是一样的。
所以python中存在两种类型的字符串,
<type 'str'> #所有其他编码的字符串都按字节以ascii码表示
<type 'unicode'> #unicode编码表示,一个符号占两个字节
encode / decode 可以实现 unicode编码与其他编码之间的转换
u'ABC'.encode('utf-8') # 'ABC'
英文字符转换后表示的UTF-8的值和Unicode值相等(但占用的存储空间不同),
u'中文'.encode('utf-8') # '\xe4\xb8\xad\xe6\x96\x87'
中文字符转换后1个Unicode字符将变为3个UTF-8字符,
你看到的\xe4就是其中一个字节,
因为它的值是228,没有对应的字母可以显示,所以以十六进制显示字节的数值。
由于Python源代码也是一个文本文件,
所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。
当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这行:
# -*- coding: utf-8 -*-
________________________________________________________________________
在python2中,字符串有两种类型
<type 'str'> 除了unicode以外的所有编码ascii, utf-8, gb2312)的字符串都是这种类型,只是字符串的编码不同
<type 'unicode'>
decode的作用是把采用其他编码的字符串(即str类型字符串)解码为unicode编码
str1.decode('gb2312') #str1采用gb2312编码,输出为unicode编码
encode的作用是把采用unicode编码的字符串编码为其他编码(即str类型字符串)
str2.encode('utf-8') #str2采用unicode编码,输出为utf-8编码
转码时一定要搞清楚原字符串采用的是什么编码。
原字符串的默认编码与代码文件本身的编码一致
在utf-8文件中的字符串是utf-8编码
在gb2312文件中字符串是gb2312编码
unicode字符不能调用decode()
非unicode字符不能串调用encode()函数,会报错
存在一个特例是,如果原unicode字符全在ascii字符范围内时,不会报错
在新版本的python3中,取消了unicode类型,
代替它的是使用unicode编码的字符串类型(str),字符串类型(str)成为基础类型。
python3中,字符串有两种类型
<type 'str'> 实际上就是用unicode编码的字符串,也就是python2中unicode类型
<type 'bytes'>
如下所示,而编码后字符串的变为了字节类型(bytes)但是两个函数的使用方法不变:
decode encode
bytes ------> str(unicode)------>bytes
u = '中文' #指定字符串类型对象u
str = u.encode('gb2312') #以gb2312编码对u进行编码,获得bytes类型对象str
u1 = str.decode('gb2312')#以gb2312编码对字符串str进行解码,获得字符串类型对象u1
u2 = str.decode('utf-8')#如果以utf-8的编码对str进行解码得到的结果,将无法还原原来的字符串内容
__summary____________________________________________________________________________________
在python2中
unicode采用unicode编码,所有一个字符用两个字节表示
其他编码(ascii, gb2312, utf-8)都是str类型,
在ascii中,一个字符用一个字节表示,所以这个字符的这个字节被表示为一个ascii字符
在其他编码方式中,一个字符可能由多个字节表示。
以gb2312为例,
s='中' # 系统默认编码是gb2312,utf-8也类似
t='\xd6\xd0' # d6为一个字节,d0为一个字节,总长为两个字节
# '中'这个字符由两个字节表示,而s这个变量的值占两个字节,
# 这两个字节在python中被表示为两个ascii字符,即表示为'\xd6'和'\xd0'这个两个ascii字符
s==t # True
len(s) # 长度为2,一个字符被编码为两个字节,而这个字符的两个字节被表示为为两个ascii字符
在python3中,
str采用unicode编码,所以一个字符用两个字节表示
s=u'中'
t=u'\u4e2d' # 4e 2d 两个字节
s==t # True
len(s) # 长度为1,一个字符占两个字节
bytes采用其他编码方式编码,每个字符可能用多个字节表示,但是每个字节为一个单位
测试发现
python中字符串的默认编码编码为
中文 'gb2312'
test='中文'
test1=u'中文' #test==test1 False
test2=test1.encode('gb2312') #test==test2 True
test3=test1.encode('utf-8') #test==test3 False
测试未发现英文字符采用的什么编码
下面发现系统默认编码为ascii
常用工具
ord('a') #获取ascii字符的整数表示
chr(97) #把编码转换成相应的字符
sys.getdefaultencoding() #获取系统的默认编码
str1.__class__ #只能查看str1的类型为unicode还是str
——————————————————————————I am just a line!——————————————————————————
有关编码
ascii码就不说了
用一个字节来编码了一个大小为128的字符集
ascii码用来表示中文就够了,但是用来表示其他语言远远不够
存在各种各样的其他语言的编码,比如
gb2312 中文编码 Shift_JIS 日文 Euc-kr 韩国
unicode
unicode把所有语言统一到一套编码里
最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。
unicode的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS。
UCS可以看作是"Unicode Character Set"的缩写。
UCS规定了怎么用多个字节表示各种文字。
UCS有两种格式:UCS-2和UCS-4。
UCS-2就是用2个字节编码,(常用的)
UCS-4就是用4个字节编码。(实际上只用了31位,最高位必须为0)
UCS-4根据最高位为0的最高字节分成2^7=128个group。
每个group再根据次高字节分为256个plane。
每个plane根据第3个字节分为 256行 (rows),每行包含256个cells。
当然同一行的cells只是最后一个字节不同,其余都相同。
group 0的plane 0被称作Basic Multilingual Plane, 即BMP。
或者说UCS-4中,高两个字节为0的码位被称作BMP。
将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。在UCS-2的两个字节前加上两个零字节,就得到了UCS-4的BMP。
而目前的UCS-4规范中还没有任何字符被分配在BMP之外。
所以,unicode编码通常是2个字节。
UTF
UCS规定了怎么用多个字节表示各种文字。
但是,因为某些原因,又产生了UTF编码(这个原因是什么,我暂时还不知道,)
个人感觉是为了传输的效率,而且从UTF的名称来看也是为了传输的效率。
用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。
UTF是由IETF规定的用于传输unicode编码的一组规范。(RFC27)
UTF(Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,
常见的UTF规范包括UTF-8、UTF-7、UTF-16。
utf-8
utf-8就是以8位为单元对UCS进行可变长编码。
utf-8本质是按照一定的规则把Unicode编码转化为“可变长编码”的UTF-8编码。
UTF-8编码把一个unicode字符根据不同的数字大小编码成1-6个字节,
常用的英文字母被编码成1个字节,
汉字通常是3个字节,
只有很生僻的字符才会被编码成4-6个字节。
utf-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是utf-8编码的一部分,
utf-16
utf-16以16位为单元对UCS进行编码。
对于小于0x10000的UCS码,UTF-16编码就等于UCS码对应的16位无符号整数。
对于不小于 0x10000的UCS码,定义了一个算法。
不过由于实际使用的UCS2,或者UCS4的BMP必然小于0x10000,
所以就目前而言,可以认为UTF -16和UCS-2基本相同。
但UCS-2只是一个编码方案,UTF-16却要用于实际的传输,所以就不得不考虑字节序的问题。
有关encode和decode http://m.jb51.net/article/17560.htm
有关各种编码 http://blog.csdn.net/moodytong/article/details/8136258