解释以下几个问题:

(1)python2中str和unicode是两种字符串类型,与字符编码方式是什么关系?

(2)str和unicode是怎么相互转换的?

(3)'\x...';'\u...', '\U...'; u'...',u'\u...',u'\U...'这些都是什么意思?

(4)字符“汉”在str类型下显示为 '\xe6\xb1\x89',在unicode类型下为啥是这样: u'\u6c49',两者之间什么关系?

(5)unicode-escape又是啥?

回答如下:

一、字符编码

  首先一点是“字符编码”(charcater coding)问题,即每个字符与某个数值(编码)的一一映射

称为码位值(code point or code position)。早期的ASCII编码用8位二进制(一个字节),

即数值0~255范围编码了128个字符,因为英文字母就那26个,加上大小写以及一些标点符号,也够用了。

但是各国语言符号多种多样,0~255范围显然不够用,于是又有了GBK等各种编码,

最后,为了编码所有的字符,产生了统一标准:Unicode(此Unicode非pyhton中的unicode类型),

各种字符都能在Unicode中找到对应的码位值。

  注:在下文中,各种进制用英文缩写代替:十进制:DEC,十六进制:HEX, 二进制:BIN

  比如,汉字字符“汉”在Unicode下的码位值为:

DEC 27721
HEX 6c49
BIN 0110 1100 0100 1001

  接下来的问题就是,Unicode具体怎样存储和传输,如果用两个字节,最大就是65535,汉字据说有超过十万个,

再加上其他语言的字符,这显然不够,需要更多字节。Unicode有两种格式:UCS-2和UCS-4,UCS-2就是用2个字节,

UCS-4用4个字节,4个字节最大可达42亿,应该是够了。但是,假如为了涵盖各种字符编码,每个字符都用4个字节,

那在存储和传输中就浪费了大量空间,比如英文字母只需一个字节,而字符“汉”只需两个字节。为了节省空间,

变长编码应运而生,但是计算机在读取二进制编码时,怎么知道一个字符该读几个字节,这就需要把字符所需字节数的信息

也编码到二进制中,UTF-8就是这样的编码

  在UTF-8中,对于单字节字符,UTF-8兼容ASCII,两者编码相同;对于多字节字符,字节数的信息编码在第一个字节中,

字节数用1的个数表示,再用0隔开,接着是原来的Unicode编码,后面每个字节均以10开头,具体如下所示:

  还是以字符“汉”为例,来对比下Unicode编码和UTF-8编码,

其中,utf8二进制前4个数为1110,即表示此字符占用三个字节

Unicode(HEX) 6c 49
Unicode(BIN)  ,   
UTF-8(BIN) 1110 ,  1011 ,  10 
UTF-8(HEX)  e6 b1 89

二、str和unicode

  python2中的strunicode是两种字符串类型(class)。

  unicode就是以Unicode编码为基础的字符串类型,赋值格式为u'xxx',

相较于一般的字符串赋值,多了一个前缀"u",还是以字符“汉”为例,我看到的格式有三种:

#  === 第一种,直接是字符 ===
In [10]: u'汉'
Out[10]: u'\u6c49'
In [11]: print u'汉'
汉 # === 第二种,双字节十六进制,\u小写 ===
In [14]: u'\u6c49'
Out[14]: u'\u6c49'
In [15]: print u'\u6c49'
汉 # === 第三种,四字节十六进制,\U大写 ===
In [16]: u'\U00006c49'
Out[16]: u'\u6c49'
In [17]: print u'\U00006c49'

注意如果把第三种中的4个0省掉,会报错

  str是另一种字符串,用于存储和传输的编码字符串,因此不同于unicode类型,

unicode类型字符串需要经过再次编码(encode)得到str类型字符串。

In [19]: su = u'汉'
In [20]: su
Out[20]: u'\u6c49'
In [21]: s = su.encode('utf8')
In [22]: s
Out[22]: '\xe6\xb1\x89' # 三个字节构成
In [23]: print s

In [24]: sg = su.encode('gbk')
In [25]: sg
Out[25]: '\xba\xba' # 两个字节构成
In [26]: print sg
ºº # 环境默认编码不是gbk,因此显示乱码 In [30]: len(su)
Out[30]: 1
In [31]: len(s)
Out[31]: 3
In [32]: len(sg)
Out[32]: 2

反过来,str也可以解码(decode)得到unicode类型。(这里的“\x”是十六进制转义的意思,后面跟的是十六进制数字)

In [34]: s.decode('utf8')
Out[34]: u'\u6c49'
In [35]: print s.decode('utf8')
汉 In [36]: sg.decode('gbk')
Out[36]: u'\u6c49'
In [37]: print sg.decode('gbk')

即:

      str              -- (decode) -->         unicode

      unicode     -- (encode) -->          str

  

  还有一个问题,字符串'\u6c49'是什么意思,注意这里的'\u6c49'str类型。

In [40]: ss = '\u6c49'
In [41]: ss
Out[41]: '\\u6c49'
In [42]: print ss
\u6c49 In [44]: ss.decode('unicode-escape')
Out[44]: u'\u6c49' In [45]: print ss.decode('unicode-escape')

这其实表示的是unicode-escape编码的str变量,类似的还有'\U00006c49'

In [52]: ss = '\U00006c49'

In [55]: ss.decode('unicode-escape')
Out[55]: u'\u6c49'
In [56]: print ss.decode('unicode-escape')

完毕。

参考文章

【1】字符编码笔记:ASCII,Unicode和UTF-8 by 阮一峰

【2】 https://www.zhihu.com/question/31833164 关注刘志军的回答

【3】 http://www.pitt.edu/~naraehan/python2/unicode.html  handling unicode.

python字符编码与解码 unicode,str的更多相关文章

  1. 【转】python 字符编码与解码——unicode、str和中文:UnicodeDecodeError: 'ascii' codec can't decode

    原文网址:http://blog.csdn.net/trochiluses/article/details/16825269 摘要:在进行python脚本的编写时,如果我们用python来处理网页数据 ...

  2. Python字符编码详解,str,bytes

    什么是明文 “明文”是可以是文本,音乐,可以编码成mp3文件.明文可以是图像的,可以编码为gif.png或jpg文件.明文是电影的,可以编码成wmv文件.不一而足. 什么是编码?把明文变成计算机语言 ...

  3. 【ABAP系列】SAP ABAP 字符编码与解码、Unicode

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP 字符编码与解码 ...

  4. Python 字符编码 zz

    http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html 1. 字符编码简介 1.1. ASCII ASCII(American Stan ...

  5. Python字符编码详解

    1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有 ...

  6. 【转】Python字符编码详解

    转自:http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html 1. 字符编码简介 1.1. ASCII ASCII(American S ...

  7. Python字符编码讲解

    声明:本文参考 Python字符编码详解 在计算机中我们不管用什么语言和程序,最终数据在计算机中的都是字节码(也就是01形式)的形式存在的,如果 计算机直接把字节码显示在屏幕上,很明显一般人看不懂字节 ...

  8. Python2/3的中、英文字符编码与解码输出: UnicodeDecodeError: 'ascii' codec can't decode/encode

    摘要:Python中文虐我千百遍,我待Python如初恋.本文主要介绍在Python2/3交互模式下,通过对中文.英文的处理输出,理解Python的字符编码与解码问题(以点破面). 前言:字符串的编码 ...

  9. 深入理解Python字符编码--转

    http://blog.51cto.com/9478652/2057896 不论你是有着多年经验的 Python 老司机还是刚入门 Python 不久,你一定遇到过UnicodeEncodeError ...

随机推荐

  1. 关于EK Dicnic

    笔记--最大流  $EK$ $Dinic$ $EK$: 运用反向边可以给当前图一次反悔的机会,就是其实现在的增广路并不是最优的,然后就$bfs$找增广路即可 $Dicnic$: 我们发现其实每一次先$ ...

  2. Independence.

    It's not giving up, it's letting go, and moving to a better place. I will survive and be the one who ...

  3. PHP网页架站

    目前,Windows下已经有集成的PHP网页架站工具,例如:AppServ.WampServer.这些软件将Apache.PHP.MySQL.phpMyAdmin集成到一起,极大地方便了开发者架站.但 ...

  4. 【NOIP】提高组2016 蚯蚓

    [题目链接]Universal Online Judge [题解]本题最大的特点在于从大到小切以及切分规则一致,都是切成px和x-px. 由这两个特点很容易得到结论,后切的蚯蚓得到的px一定比先切的蚯 ...

  5. 【BZOJ】2705: [SDOI2012]Longge的问题

    [题意]给定n,求∑gcd(i,n),(1<=i<=n),n<=2^32 [算法]数论(欧拉函数,gcd) [题解]批量求gcd的题目常常可以反过来枚举gcd的值. 记f(g)为gc ...

  6. 【洛谷 P2754】 [CTSC1999]家园(最大流)

    题目链接 突然发现Dinic很好写诶.. 第一次数组开小了,玄学\(WA\),what?数据范围描述有误? 分层图,每天为一层. 把上一天的每个空间站向这一天连一条流量为inf的边,表示可以原地不动. ...

  7. HDU 1026 Ignatius and the Princess I (广搜)

    题目链接 Problem Description The Princess has been abducted by the BEelzebub feng5166, our hero Ignatius ...

  8. 父元素与子元素之间的margin-top问题(css hack)

    hack: 父元素的盒子包含一个子元素盒子,给子元素盒子一个垂直外边距margin-top,父元素盒子也会往下走margin-top的值,而子元素和父元素的边距则没有发生变化. hytml代码: &l ...

  9. HTML -- get与post提交方式的区别 -- (转)

    在写代码过程中,get与post是两种不同的提交方式.下面,列举出两种方式的不同. 方法/步骤   get是从服务器上获取数据,post是向服务器传送数据.   get是把参数数据队列加到提交表单的A ...

  10. hdu 1869 六度分离(最短路floyd)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1869 六度分离 Time Limit: 5000/1000 MS (Java/Others)    M ...