关于python编解码的一些坑(一)

学过python的都知道,python的encode,decode里面有一些坑,掉进去后比较难爬出来。正好这段时间想总结一下这些坑,我会写2-3篇文章来介绍我对这些坑的理解。既然是个人理解,那很可能有些考虑不对的地方。因此如果大家自认为有更准确的理解,也希望能相互交流,共同学习,一起进步!另,文章中引用的文献,我都做了说明,也都注明了出处,以方便大家查阅。

文章比较长,基本是我一手敲下来的来

一,str 和 unicode
1) str 和 unicode 都是basestring的子类。
str典型编码类型:gbk,utf8; 表现形式:\xc4\xe3\xba\xc3。若是你看到类似于\xc4\xe3这种类型的编码,你首先要搞清楚,这个应该是中文编码经过gbk或utf8或其他类型的编码(总归不是unicode编码),至于到底是gbk还是utf8,不知道!而看到类似于\u4f60,就需要明白,这个是中文的unicode编码或者说是unicode表示,未经具体的utf8或gbk编码
2) str是经过编码的(采用何种编码取决于你的python编辑器,典型的如gbk, utf8。如笔者在cmd中默认为gbk编码),典型形式:\xc4\xe3。
3) unicode 没有经过编码。这里可以认为是有一个“统一世界”,在这个世界里,所有人类世界中的字符(如英文字符,中文字符,阿拉伯字符,希腊字符等等)都有一个统一的代号。典型形式:\u4f60。
4) str是字节串,表现形式 ” ” 或’ ’ 。是unicode经过encode编码后的字节所组成;

>>> s1="你好"
>>> s1
'\xc4\xe3\xba\xc3'
>>> len(s1)
4
>>> s2="hello"           #注意,后面“补充解释”会讲到
>>> s2   
'hello'     
>>> len(s2)
5

而unicode才是真正的字符串,表现形式为u” ”

u1=u"你好"
>>> u1
u'\u4f60\u597d'
>>> len(u1)
2
>>> u2=u'hello'          #注意,后面“补充解释”会讲到
>>> u2
u'hello'           
>>> len(u2)
5

根据上面的四点,这里要补充解释几个方面
str和unicode的典型表形式,为何他们长成这个样子
先说unicode。“unicode目前普遍采用的是UCS-2标准,它用两个字节来表示(这里说“表示”,而不是“编码”,因为我觉得这样更加准确)一个字符,故UCS-2最多只能表示65536个字符。汉字简体繁体加起来超过了7万个,但是UCS-2最多只能表示65535个字符,故肯定有部分汉字是UCS-2编码无法表示的,UCS-2的处理办法是是排除一些几乎不用的汉字。另外,为了表示所有的汉字,unicode有UCS-4编码规范,即用四个字节来表示字符串”(——百度百科)。
就拿\u4f60来说,它是中文“你”的UCS-2表示。\u 表示是unicode,4f60是用十六进制表示的两个字节。
因此,今后我们碰到类似“\u—-”这种东东,我们要形成的条件反射是:首先它未经过编码,它只是“某个字符”在统一世界一个统一代码表示,它完全等同于“某个字符”。它是真正的“字符串”。

再说具体的编码形式,如“utf8” 和 “gbk”
无论是utf8和gbk,他们所做的工作都是把unicode字符进行编码,只是编码的规则不同。从表象来看,他们都是表现为字节串的形式。
如中文“你”(unicode为“\u4f60”)的utf编码为: “\xe4\xbd\xa0”;而gbk的编码为:“\xc4\xe3”。他们长得差不多,因此如果你看到了这种“\x–\x–\x–\x–\x–\x–”,我们要形成的条件反射是:首先它是某种编码,它是“字节串”,我们无法肯定它到底是哪种编码(python提供了判断这种字节串可能是哪种编码方式的API:chardet(),注意判断的结果只是可能是某种编码,并告知我们这种可能性有多大)。

 UTF-8和unicode的关系
utf-8只是unicode的一种具体的实现方式。utf8是针对unicode变长编码设计的一种前缀码,根据前缀可判断是几个字节表示一个字符,如下图:
这里写图片描述

如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。
比如”严”的unicode是4E25(100111000100101),4E25处在第三行的范围内(0000 0800-0000 FFFF),因此”严”的UTF-8编码需要三个字节,即格式是”1110xxxx 10xxxxxx 10xxxxxx”。然后,从”严”的最后一个二进制位开始,依次从后向前填入格式中的x,高位补0,得到”严”的UTF-8编码是”11100100 10111000 10100101”。
可以发现:对于0x00-0x7F之间的字符,十进制范围是0–127,UTF-8编码与ASCII编码完全相同。可以得到进一步的结论,由于ASCII是计算机发展史上最早的编码规范,它之后所发展的一些编码规范,典型如utf-8,gb2312等都完全兼容ASCII码。

解释第四点4)中的举例。中文、英文在unicode和gbk的表现形式
先拿例子说话:(在cmd中,编码格式为gbk) <

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值