python编码恩怨录

在python里面,中文的编码问题是特别麻烦的问题,所以为了更好的解决这个问题,就简单整理关于编码的内容

1.编码背景:

比特与字节:

都知道计算机其实最终都会把所有的信息都变成0,1二进制比特位(bit),但是如果都是01这样的数字,正常人肯定记不住,所以就会最开始用8个二进制来表示一个字节(byte)。

ASCII码:

20世纪初的时候,美国制定了一套字符编码,将英文与二进制进行了一个对应,这个就是现在还在使用的ASCII码。ASCII码就是一个字节,按理是应该有256个字符,但是其实只有128个字符编码,这是因为首位统一规定为0,后面七位才进行编码,所以就是2^7个

非ASCII码:

ASCII码是专门为英文设计的编码,但是对于其他语言来说,并不友好,特别像中文这种,128个字符编码可能连日常常用的字都没办法覆盖。所以大家就开始要对自己国家文字进行一个编码。这样看似解决了编码问题,但是就会出现同样的一个二进制数字存有多个对应的文字。正是这个问题的存在,提出了Unicode。

Unicode:

Unicode是一个很大的符号集(像GBK,GB都是这类),采用16进制,可以容纳100多万个符号,保证每个符号编码都不一样。

但问题也正是出字Unicode是一个符号集,并没有给出这个二进制要如何存储。比如,汉字严,unicode是十六进制的4E25,二进制有15位,那么要两个字节表示。之前说过,ascii码只有1个字节,所以这个时候,计算机要怎么知道这个是表示1个汉字还是2个英文字母呢?其次,如果unicode都是3、4字节表示,但是其实英文只要1个字节就够了,那这就会造成浪费。

UTF-8:

UTF-8就是为了Unicode的一个存储实现方案,为的就是解决unicode之前出现的问题。UTF-8最大特点就是是一个灵活的编码方式,它可以用1~4个字节表示一个符号,这样就很好的兼容了ascii码和unicode码。

编码方式:

1.对于单字节符号,字节第一位设为0,后面7位为unicode码。这个其实就是等价与ascii码了。 

2.对于n个字节符号(n>1),则第一个字节前n位为1,n+1为0,然后后面的字节都前两位10开头。(可以理解为,第一个字节要告诉计算机这是用了几位字节表示了这个符号,后面前两位表示是这个第一个字节的“兄弟”) 

2.Python编码:

py文件中的编码:

Python默认脚本是用ASCII编码的,当文件中有非ASCII编码的字符出现后,就要使用“编码指示”来修正一个module的定义中,如果.py文件中包含中文字符,则需要在第一行或者第二行指定编码声明: # -*- coding: utf-8 -*-

Python中的字符串类型:

Python字符串类型有两种类型,一个是str和unicode,他们都是basestring的派生类

Str类型是一个包含Characters represent (at least) 8-bit bytes的序列; 

unicode的每个unit是一个unicode obj 

一般来说,如果出现前面带u就是unicode编码。
在读取每一个文件内容,或者是网络内容时,保持的对象为str类型,如果想到str转成特定编码类型,需要先转到unicode,然后再编码成utf-8这种。

Python中的解码与编码:

如果是unicode,这个时候可以直接指定想转成的编码:

Unicode -> GBK、GB、UTF-8:string.encode() 

如果是从其他编码方式转到另一种编码方式,如果utf-8到gbk,就要先解码成unicode,再从unicode编码:

UTF-8/GBK...  -> Unicode -> GBK/...: string.decode().encode() 

当然,有的人可能会觉得比较麻烦,如果他处理的全是utf-8的编码转成gbk,每次都这样写可能会觉得很麻烦,这个时候,可以直接使用sys.defaultencoding()(通常sys.defaultencoding默认是ascii)来指明方式解码,然后程序直接string.encode()就可以了。

参考文献:

http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

https://blog.csdn.net/wzb56_earl/article/details/73823437

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值