python字符串编码问题
常见编码格式
ASCII编码
一个字节可以表示所有字符,原始的ASCII标准定义了从0到127 的字符,这样正好能用七个比特表示
GB2312
ASCII不能表示所有的中文,所以中国制定GB2312编码,用两个字节表示一个汉字。
GB2312包含ASCII编码
unicode
统一采用两个字节编码,原ASCII在高位补0
但使得原来纯英文存储的数据现在需要两倍的存储空间
UTF-8
可变长的编码,英文继续按照原来的一个字节编码汉字采用3个字节编码
unicode与utf-8比较
unicode:简单粗暴,所有字符都是2Bytes,优点是字符----->数字的转换速度快,缺点是占用空间大。
utf-8:精准,对不同的字符用不同的长度表示,优点是节省空间,缺点是:字符->数字的转换速度慢,因为每次都需要计算出字符需要多长的Bytes才能够准确表示。
因此,内存中使用的编码是unicode,用空间换时间(程序都需要加载到内存才能运行,因而内存应该是尽可能的保证快);硬盘中或者网络传输用utf-8,网络I/O延迟或磁盘I/O延迟要远大与utf-8的转换延迟,而且I/O应该是尽可能地节省带宽,保证数据传输的稳定性。
python内存编码
python2中
对某个字符串采用utf-8的编码时,必须保证该字符串是unicode编码
windows下对带中文字符进行utf-8编码的话是行不通的
因为windos默认的编码为GB2312,所以需要将字符串编码解码成unicode,在编码成utf-8
并且sys.defaultencoding() = utf-8,encode函数调用前会,先对字符串做decode操作,而decode默认使用系统的GB2312解码,这就导致出错了
string.decode("GB2312").encode("utf-8")
linux下对带中文字符进行utf-8编码的话是行不通的
因为linux默认的编码格式是utf-8,但是为什么对utf-8的编码在采用utf-8编码行不通呢?
因为sys.defaultencoding() = ascii,encode函数调用前会,先对字符串做decode操作,而decode默认使用系统的ascii解码,这就导致出错了
string.decode("utf-8").encode("utf-8")
python3中
默认编码格式为utf-8
所以string.encode('utf-8')就不会有报错
内存中统一采用unicode来编码
不代表内存中全都是unicode编码的二进制,在程序执行之前,内存中确实都是unicode编码的二进制,比如从文件中读取了一行x="string",其中的x,等号,引号,地位都一样,都是普通字符而已,都是以unicode编码的二进制形式存放与内存中的.但是程序在执行过程中,会申请内存(与程序代码所存在的内存是俩个空间),可以存放任意编码格式的数据,比如x="string",会被python解释器识别为字符串,会申请内存空间来存放"string",然后让x指向该内存地址,此时新申请的该内存地址保存也是unicode编码的string,如果代码换成x="string".encode('utf-8'),那么新申请的内存空间里存放的就是utf-8编码的字符串hello了
声明文件编码格式
如果代码中出现了中文,想要正常显示的话建议在代码第一行或第二行添加语句
这个的作用是声明代码中将会出现中文,并且会将文件中的字符串使用此编码转换成unicode对象,在encode编码时,很大程度避免了默认解码带来的问题
#-*- coding:utf-8 -*-