解释以下几个问题:

(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. 【BZOJ 2322】[BeiJing2011]梦想封印 利用"环基"+线性基特征值

    很容易想到离线加边并且把环和链拆开搞(就是对于每个终点求出起点到他的路径(其实就是dfs树),然后bzoj2115),而且维护也很简单,然而我们发现不同的终点可能得到相同的值,这就是我们遇到的最大的问 ...

  2. PowerDesigner 技巧【2】

    去掉Oracle生成的SQL创建语句中的双引号 用powerdesigner导出orale数据库的建表sql时,默认会给表名和字段名加上双引号,如下图: 这样给操作数据库带来很大的不便,解决的办法是设 ...

  3. New Year and Domino 二维前缀和

    C. New Year and Domino time limit per test 3 seconds memory limit per test 256 megabytes input stand ...

  4. 学习opencv-------函数使用二(图像变换)

    #include"cv.h" #include"highgui.h" using namespace cv; void CVFILTER2D(IplImage ...

  5. FreeRTOS - 任务使用注意

    如果使用xTaskCreate() 创建任务,任务栈使用的是FreeRTOS heap

  6. Oracle raw类型

    RAW(size):长度为size字节的原始二进制数据,size的最大值为2000字节; RAW类型好处:在网络中的计算机之间传输 RAW 数据时,或者使用 Oracle 实用程序将 RAW 数据从一 ...

  7. Update SSM agent to each EC2 via Bat and bash script

    1. copy the instance id from aws console to file 2. remove the , from file sed -i 's/,//g' file 3. g ...

  8. div模拟textarea在ios下不兼容的问题解决

    今天发现一个好东西,赶紧记下来,我在用textarea的时候,想要自适应高度,这样就不会出现滚动条.网上找了很多,都是用div模拟的,但是好扯淡,div模拟的在ios下不能聚焦并且不能输入.真坑... ...

  9. linux下输出查看进程及杀进程

    1.查找有关tomcat的进程 ps -ef | grep tomcat 2.查看某端口占用情况 netstat -tulpn | grep 9009 3.杀进程 普通:kill 进程id 强制:ki ...

  10. Linux修改服务器ip

    Linux基础二(修改ip地址.修改网关.修改DNS服务器.重新启动网络配置)   网络的初始化 .ip地址的修改(临时生效) 使用ifconfig命令 ifconfig 网卡名 ip地址 netma ...