python高级(四)—— 文本和字节序列(编码问题)

2018-02-28 07:45:44来源:cnblogs.com作者:廖Sir人点击

分享
第七城市

本文主要内容

字符

字节

结构体和内存视图

字符和字节之间的转换——编解码器

BOM鬼符

   明天继续。。。

python高级——目录

文中代码均放在github上:https://github.com/ampeeg/cnblogs/tree/master/python高级

字符

'''    字符编码问题是经常困扰python编程人员的问题,我在编写爬虫的过程中也经常遇到这个头疼的事。    从python3开始,明确区分了人类语言(文本字符串)和机器语言(二进制字节),咱们先说文本字符串    开始之前,得对"字符"进行定义:        字符:Unicode字符,从python3的str对象中获取的元素是Unicode字符        字符串:字符串就是一个字符序列(这里对于(一)中内容相呼应)'''if __name__ == "__main__":    # 创建字符    s1 = str('a')    s2 = 'b'    s3 = u'c'    print(s1, s2, s3)      # a b c

   

  此时只用记住在python3中字符就是unicode,也就是str是unicode,这是人类能够看懂的语言。

字节

'''    python3中内置有两种基本的二进制序列类型:不可变的bytes和可变bytearray        (1)bytes和bytearray的各个元素是介于0~255(8个bit)之间的整数;        (2)二进制序列的切片始终是同一类型的二进制序列'''if __name__ == "__main__":    # 创建bytes 和 bytearray    b1 = bytes('abc你好', encoding='utf8')      # 关于encode稍后会说,不知道有没有人和我一样总是将编码与解码的方向混淆    print(b1)          # b'abc/xe4/xbd/xa0/xe5/xa5/xbd'    b2 = bytearray('abc你好', encoding='utf8')    print(b2)          # bytearray(b'abc/xe4/xbd/xa0/xe5/xa5/xbd')    # 切片(提示:序列都可以切片)    print(b1[3:5])     # b'/xe4/xbd'    print(b2[3:5])     # bytearray(b'/xe4/xbd')    # 使用列表取值的方法试试    print(b1[3])       # 228 此时取出来的就不是字节序列了,而是一个元素    for _ in b1:        print(_, end=',')   # 97,98,99,228,189,160,229,165,189,      这都是8bit的整数    # bytes的不可变 vs. bytearray的可变    # b1[3] = 160           # 报错:'bytes' object does not support item assignment    print(id(b2), b2)      # 4373768376 bytearray(b'abc/xe4/xbd/xa0/xe5/xa5/xbd')    b2[2] = 78    print(id(b2), b2)      # 4373768376 bytearray(b'abN/xe4/xbd/xa0/xe5/xa5/xbd')    # 将b2转换成字符串看看    print(b2.decode('utf8'))  # abN你好                              # 注意,这里之所以能够用utf8转成unicode,是因为N的ascii码和utf8一致    b2.extend(bytearray('添加的内容', encoding='utf8'))  # 既然是可变序列,bytearray当然拥有一般的序列的方法    print(id(b2), b2)         # 4373768376 bytearray(b'abN/xe4/xbd/xa0/xe5/xa5/xbd/xe6/xb7/xbb/xe5/x8a/xa0/xe7/x9a/x84/xe5/x86/x85/xe5/xae/xb9')    print(b2.decode('utf8'))  # abN你好添加的内容    # PS:大家可以将二进制序列当成列表,元素就是ascii编码(0~255)

结构体和内存视图

'''    struct可以从二进制序列中提取结构化信息。    struct模块提供了一些函数,可以将打包的字节序列转换成不同类型字段组成的元组;还有一些函数用于执行反向转换。    struct模块可以处理bytes、bytearray、memoryview对象。'''import structif __name__ == "__main__":    # memoryview类用于共享内存,可以访问其他二进制序列、打包的数组和缓冲中的数据切片,该操作无需赋值字节序列    fmt = '<3s3sHH'   # 设置格式,< 是小字节序,3s3s是两个3字节序列,HH是两个16位二进制整数    with open('L3_图_python.jpg', 'rb') as f:        img = memoryview(f.read())    print(bytes(img[:10]))    # b'/xff/xd8/xff/xe0/x00/x10JFIF/x00/x01/x01/x02/x00/x1c/x00/x1c/x00/x00'    print(struct.unpack(fmt, img[:10]))   # (b'/xff/xd8/xff', b'/xe0/x00/x10', 17994, 17993)  :拆包    del img

字符和字节之间的转换——编解码器

'''    python自带有超过100中编解码器,用于在字符串和字节之间相互转换。    每个编码都有多个名称,例如'utf_8'、'utf8'、'utf-8'、'U8',这些都可以传递给open()、str.encode()、bytes.decode()中的    encoding参数'''if __name__ == "__main__":    # 看看不同的编码效果    for codec in ['gbk', 'utf8', 'utf16']:        print(codec, "你好".encode(codec), sep='/t')    '''                        gbk      b'/xc4/xe3/xba/xc3'                        utf8    b'/xe4/xbd/xa0/xe5/xa5/xbd'                        utf16    b'/xff/xfe`O}Y'    '''    # 咱们再来解码    print(b'/xc4/xe3/xba/xc3'.decode('gbk'))            # 你好    print(b'/xe4/xbd/xa0/xe5/xa5/xbd'.decode('utf8'))   # 你好    print(b'/xff/xfe`O}Y'.decode('utf16'))              # 你好
'''    遇到编码问题一般很烦躁,下面来看看一般怎么解决编码问题。    (1)UnicodeEncodeError     (2) UnicodeDecodeError'''if __name__ == "__main__":    # (1)UnicodeEncodeError    # 使用errors参数    s1 = "hello,你长胖啦".encode('latin-1', errors='ignore')    print(s1)   # b'hello'    使用 errors='ignore' 忽略了无法编码的字符    s2 = "hello,你长胖啦".encode('latin-1', errors='replace')    print(s2)   # b'hello?????'    使用errors='replace'将无法编码的字符用问好代替    s3 = "hello,你长胖啦".encode('latin-1', errors='xmlcharrefreplace')    print(s3)   # b'hello&#65292;&#20320;&#38271;&#32982;&#21862;'  使用errors='xmlcharrefreplace'将无法编码的内容替换成XML实体    # (2) UnicodeDecodeError    # 乱码字符称为鬼符,以下实例演示出现鬼符的情况    s4 = b'Montr/xe9al'    print(s4.decode('cp1252'))    # Montréal    print(s4.decode('iso8859_7')) # Montrιal    print(s4.decode('koi8_r'))    # MontrИal    #print(s4.decode('utf8'))      # 报错:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 5: invalid continuation byte    print(s4.decode('utf8', errors='replace'))   # Montr�al

  明天继续。。。

python高级系列文章目录

python高级——目录

第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台