1.什么是字符编码:
计算机是基于电工作的(产生高低电平),人们根据高低电平从逻辑的角度使高电平代表1,低电平代表0 ,所以机器语言的二进制编码是计算机所能直接认知的(无需转换),而无论是汇编语言还是高级语言它们的字符都需要根据某种映射关系使字符变成计算机所能理解的数字,这一过程所对应的映射关系(标准)就叫字符编码
字符 -------------(根据字符编码)---------->数字
2.字符编码的发展史:
计算机是由美国人设计出来的,它们的语言基本字母(26个字母,区分大小写)加上其它的符号(,/等)以及后来编入的拉丁字符也就是200多个,以0,1代表两种字符,只需要使用二进制的8位(256种),即可映射所有字符与数字的关系,这就产生了ASCLL码,规定一个字符由8位bit位表示
后来随着计算机的普及,各国人民发现仅仅是256种映射关系是无法将自己的语言字母纳入。比如中国,常规汉字就远远不止这个数,所以中国人指定了自己的映射标准,即gb2312编码,以16位二进制数来映射字符到数字的转换。还有其它国家的Shift_JIS编码(日本),Euc-kr编码(韩国)
再后来随着全球化的发展,各国发现根据自己标准编写的文档/软件在其它国家电脑上运行会产生乱码现象(为什么?),这时就产生了包含各国语言的万国码(unicode),规定以两个字节表示一个字符(16位二进制)
但是,英文字符是八位二进制即可表示,即在unicode码中前面八位全是0,这就造成了很大的空间浪费,所以又产生了UTF-8编码,以一个字节表示英文字符,汉字通常用三个字节表示,而且ASCLL码属于UTF-8(即它们的二进制一样)
3:为什么会产生乱码现象:
产生乱码的原因其实就是字符编码的问题。----从内存刷到硬盘时的字符编码与从硬盘加载到内存时字符编码不一致
注:内存中的固定编码是unicode,我们能改变的就是存到硬盘的字符编码,假如我们在文本编辑器上编辑一个字符‘何’,他在内存中并不能说是汉字,很多国家都可以使用这个‘何’字符,他仅仅是根据Unicode转换成了数字临时的保存在内存中,当我们以编码的方式(encode)将其转换为GBK下的汉字存在硬盘中,他才是汉字,如果我以日本的字符编码将汉字‘何’解码成unicode就会乱码
4:会出现乱码的两个地方:
1.无论是python运行/写程序(编写python程序其实就是编写文本文件)还是文本编辑器读/写文本内容,前两个阶段都一样,涉及到文件的存取
2.执行python程序时,python拥有字符串数据类型(包含一系列的字符)
5.执行python程序的三个阶段:1.启动python解释器 2.将储存python程序的文件加载到内存 3.执行python语句
对于第一阶段不存在乱码问题
对于第二阶段,如果在硬盘中的字符是以gbk编码的,那么无论是在python2解释器(默认为ASCLL),还是在python3中(默认为utf-8)都会报错,必须在文件开头指定为gbk
对于第三阶段:内存中的编码是unicode,但是不完全都是unicode
程序执行之前,所以字符都是unicode格式
程序执行后,python会申请空间用于存放数据类型的值,而python字符串涉及到字符的概念(会申请空间存放字符串类型的值),至于为何种类型与解释器的默认编码有关
python3中的str是以unicode编码形式存放的,可以通过encode()编码成bytes类型,而python2中的str是py3中的bytes类型
Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> x= '你好' >>> x '\xc4\xe3\xba\xc3' >>> x.decode('gbk') u'\u4f60\u597d' Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> x='你好' >>> x '你好' >>> x.encode('gbk') b'\xc4\xe3\xba\xc3' type(x.encode('gbk')) <class 'bytes'>
python3的bytes类型有两种应用类型:
1.刷到硬盘中(unicode是不能直接存到硬盘的)
2.基于网络发送