• Python字符编码


    字符编码

    计算机只认识数字,我们平时在使用计算机时,用的都是人类能读懂的字符(用高级语言编程的结果也无非是在文件内写了一堆字符),如何能让计算机读懂人类的字符?必须经过一个过程: 字符--------(翻译过程)------->数字 这个过程实际就是一个字符如何对应一个特定数字的标准,这个标准称之为字符编码

    一、存取文件的原理(nodepad++,pycharm,word)

    • a、打开编辑器就打开了启动了一个进程,是在内存中的,所以,用编辑器编写的内容也都是存放与内存中的,断电后数据丢失
    • b、要想永久保存,需要点击保存按钮:编辑器把内存的数据刷到了硬盘上。
    • c、在我们编写一个py文件(没有执行),跟编写其他文件没有任何区别,都只是在编写一堆字符而已。

    二、编码发展

    • 阶段1:现代计算机起源于美国,最早诞生也是基于英文考虑的ASCII,ASCII:用1个字节Bytes(8位二进制)代表一个字符
    • 阶段2:为了满足中文和英文,中国人定制了GBK, GBK:2Bytes代表一个中文字符,1Bytes表示一个英文字符
    • 阶段3:各国有各国的标准,出现冲突,unicode出现了,能够兼容万国字符。 unicode(定长):常用2个字节(16位二进制)代表一个字符,生僻字需要用4个字节
    • 阶段4:对于通篇都是英文的文本来说,unicode的式无疑是多了一倍的存储空间(二进制最终都是以电或者磁的方式存储到存储介质中的)于是产生了UTF-8(可变长,全称Unicode Transformation Format)UTF-8:对英文字符只用1Bytes表示,对中文字符用3Bytes,对其他生僻字用更多的Bytes去存。

    三、乱码来源

    • 乱码1:存文件时就已经乱码
    • 存文件时,由于文件内有各个国家的文字,我们单以shiftjis去存, 本质上其他国家的文字在shiftjis中没有找到对应关系,不能存而硬存,肯定是乱存了,即存文件阶段就已经发生乱码,而当我们用shiftjis打开文件时,日文可以正常显示,而中文则乱码了。
    • 乱码2:存文件时不乱码而读文件时乱码【按照什么标准编码的,就要按照什么标准解码】
    • 存文件时用utf-8编码,保证兼容万国,不会乱码,而读文件时选择了错误的解码方式,比如gbk,则在读阶段发生乱码,读阶段发生乱码是可以解决的,选对正确的解码方式就ok了,

    四、特别说明

    • 指定头信息#-*-coding:utf-8-*- python解释器编码就是头信息编码, 没有指定头信息,那就使用默认的python2中默认使用ascii,python3中默认使用utf-8。
    • 在python2中有两种字符串类型str(编码成文件头指定的编码格式)和unicode 在python3 中也有两种字符串类型str(直接编码成unicode)和bytes python2中的str类型就是python3的bytes类型
    • 特别说明print时,open时,没指定编码格式就使用终端的编码格式。
    • sys.stdout.encoding,默认就是locale的编码,print会用sys.stdout.encoding去encode()成字节流,交给terminal显示。所以locale需要与terminal一致,才能正确print打印出中文。
    • 浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器
    • 如果服务端encode的编码格式是utf-8, 客户端内存中收到的也是utf-8编码的结果。
    • *****内存中统一采用unicode,浪费空间来换取可以转换成任意编码(不乱码),硬盘可以采用各种编码,如utf-8,保证存放于硬盘或者基于网络传输的数据量很小,提高传输效率与稳定性。*****
    • ***在存入磁盘时,需要将unicode转成一种更为精准的格式,utf-8****
    • ***在读入内存时,需要将utf-8转成unicode****

    五、python解释器执行py文件的3个阶段

    • 阶段1:启动python解释器相当于启动了一个文本编辑器
    • 阶段2:从硬盘读取test.py文件内容到内存。【此时,python解释器会读取test.py的头信息#-*-coding:utf-8-*-,来决定以什么编码格式读入到内存,可以用sys.getdefaultencoding()查看,如果没有指定头信息#-*-coding:utf-8-*-,那就使用python解释器默认的编码,python2中默认使用ascii,python3中默认使用utf-8。】
    • 阶段3:解释执行阶段。【在该阶段,才会识别python的语法,执行文件内代码,当执行到name="tom"时,会开辟内存空间存放字符串"tom"。】
    • python解释器比文本编辑器多了阶段3

    细说阶段3

    • 在程序执行之前,内存中都是unicode
    • 程序在执行过程中,会申请内存(与程序代码所存在的内存是俩个空间)用来存放python的数据类型的值,比如x="tom",会被python解释器识别为字符串,会申请内存空间来存放字符串类型的值,至于该字符串类型的值被识别成何种编码存放,这就与python解释器有关了,而python2与python3的字符串类型又有所不同。  
    • 在python2中有两种字符串类型str(编码成文件头指定的编码格式)和unicode
    • 在python3中也有两种字符串类型str(直接是unicode)和bytes (也就是python2中的str)
    • 字节字符串和字符字符串
    • (内存)unicode----->encode-------->utf-8(硬盘)
    • (硬盘)utf-8----->decode-------->unicode(内存)

    六、总结

    • 字符按照什么标准而编码的,就要按照什么标准解码
    • 在内存中写的所有字符,一视同仁,都是unicode编码,比如我们打开编辑器,输入一个“你”,我们并不能说“你”就是一个汉字,此时它仅仅只是一个符号,该符号可能很多国家都在使用,根据我们使用的输入法不同这个字的样式可能也不太一样。只有在我们往硬盘保存或者基于网络传输时,才能确定”你“到底是一个汉字,还是一个日本字,这就是unicode转换成其他编码格式的过程了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
     
    #将bytes转换为str
    name_b = b'tom'
    name_s1 = name_b.decode('utf-8')
    name_s2 = str(name_b,encoding='utf-8')
    print(name_b,type(name_b)) #b'tom' <class 'bytes'>
    print(name_s1,type(name_s1)) #tom <class 'str'>
    print(name_s2,type(name_s2)) #tom <class 'str'>
     
    #将str转换为bytes
    gender = 'male'
    gender_b1 = gender.encode('utf-8')
    gender_b2 = bytes(gender,encoding='utf-8')
    print(gender,type(gender)) #male <class 'str'>
    print(gender_b1,type(gender_b1)) #b'male' <class 'bytes'>
    print(gender_b2,type(gender_b2)) #b'male' <class 'bytes'>
  • 相关阅读:
    知乎神回复:代码之间为什么要加空格?这个问题我是这样理解的!
    经验分享:一个 30 岁的人是如何转行做程序员,进入IT行业的?
    对于程序员来说,学历真的重要吗?为何都是高学历混的风生水起?
    教材、教参、教案有哪些区别?
    教参是什么
    教师面试指要
    教师资格证结构化面试是什么?会怎么考查?
    教师资格证面试试讲时可以戴手表吗
    讲师面试流程及试讲指导
    教师资格面试:试讲和说课的区别
  • 原文地址:https://www.cnblogs.com/bubu99/p/10191271.html
Copyright © 2020-2023  润新知