首页 > 编程语言 >【4.0】Python中级之字符编码

【4.0】Python中级之字符编码

时间:2023-11-19 19:12:37浏览次数:35  
标签:编码 4.0 字符 Python 内存 unicode 格式 硬盘

【一】文本编辑器与Python解释器原理

  • 字符串类型、文本文件的内容都是由字符组成的,但凡涉及到字符的存取,都需要考虑字符编码的问题。

【1】数据存放位置

  • 所有软件都是运行硬件之上的

    • 与运行软件相关的三大核心硬件为cpu、内存、硬盘
  • 软件运行前,软件的代码及其相关数据都是存放于硬盘中的

  • 任何软件的启动都是将数据从硬盘中读入内存,然后cpu从内存中取出指令并执行

  • 软件运行过程中产生的数据最先都是存放于内存中的,若想永久保存软件产生的数据,则需要将数据由内存写入硬盘

img

【2】文本编辑器读取文件内容的流程

(1)阶段1

  • 启动一个文件编辑器(文本编辑器如nodepad++,pycharm,word)

(2)阶段2

  • 文件编辑器会将文件内容从硬盘读入内存

(3)阶段3

  • 文本编辑器会将刚刚读入内存中的内容显示到屏幕上

【3】Python解释器执行文件的流程

(1)阶段1

  • 启动python解释器,此时就相当于启动了一个文本编辑器

(2)阶段2

  • python解释器相当于文本编辑器,从硬盘上将test.py的内容读入到内存中

(3)阶段3

  • python解释器解释执行刚刚读入的内存的内容,开始识别python语法

【4】总结:文本编辑器与Python解释器的异同

(1)相同点

  • 前两个阶段二者完全一致,都是将硬盘中文件的内容读入内存,详解如下
    • python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样

(2)不同点

  • 在阶段3时,针对内存中读入的内容处理方式不同,详解如下
    • 文本编辑器将文件内容读入内存后,是为了显示或者编辑,根本不去理会python的语法
    • 而python解释器将文件内容读入内存后,可不是为了给你瞅一眼python代码写的啥,而是为了执行python代码、会识别python语法

【二】什么是字符编码

  • 人类在与计算机交互时,用的都是人类能读懂的字符,如中文字符、英文字符、日文字符等
    • 而计算机只能识别二进制数
  • 二进制数即由0和1组成的数字,例如010010101010
  • 计算机是基于电工作的,电的特性即高低电平
  • 人类从逻辑层面将高电平对应为数字1,低电平对应为数字0,这直接决定了计算机可以识别的是由0和1组成的数字
  • 所以,由人类的字符到计算机中的数字,一定经历一个过程

  • 翻译的过程必须参照一个特定的标准

    • 该标准称之为字符编码表
    • 该表上存放的就是字符与数字一一对应的关系。
  • 字符编码中的编码指的是翻译或者转换的意思

    • 即将人能理解的字符翻译成计算机能识别的数字

【三】字符编码的发展

【1】阶段一:一家独大(ASCII)

(1)ASCII表的诞生

  • 现代计算机起源于美国,所以最先考虑仅仅是让计算机识别英文字符,于是诞生了ASCII表

(2)ASCII表的特点

  • 只有英文字符与数字的一一对应关系

  • 一个英文字符对应1Bytes,1Bytes=8bit,8bit最多包含256个数字,可以对应256个字符,足够表示所有英文字符

(3)字母对应ASCII表

  • A-Z:65-90

  • a-z:97-122

  • 0-9:48-57

  • 小写字母对应的数字一定大于大写字母

img

【2】阶段二:诸侯割据(ASCII/GBK/Shift_JIS)

  • 为了让计算机能够识别中文和英文,中国人定制了 GBK

(1)GBK表的特点

  • 只有中文字符、英文字符与数字的一一对应关系

  • 一个英文字符对应1Bytes 一个中文字符对应2Bytes

  • 补充说明

    • 1Bytes=8bit,8bit最多包含256个数字,可以对应256个字符,足够表示所有英文字符
    • 2Bytes=16bit,16bit最多包含65536个数字,可以对应65536个字符,足够表示所有中文字符

(2)各国不同的编码表

  • 为了让计算机能够识别日文字符、英文字符与数字的一一对应关系,日本定制了 Shift_JIS
  • 为了让计算机能够识别韩文字符、英文字符与数字的一一对应关系,韩国定制了 Euc-kr
  • 美国人用的计算机里使用字符编码标准是ASCII
  • 中国人用的计算机里使用字符编码标准是GBK
  • 日本人用的计算机里使用字符编码标准是Shift_JIS

img

(3)多种编码共存的缺点

  • 此时无论是存还是取由于采用的字符编码表一样
    • 所以肯定不会出现乱码问题
  • 但问题是
    • 在美国人用的计算机里只能输入英文字符
    • 而在中国人用的计算机里只能输入中文字符和英文字符....
  • 毫无疑问我们希望计算机允许我们输入万国字符均可识别、不乱码,而现阶段计算机采用的字符编码ASCII、GBK、Shift_JIS都无法识别万国字符
    • 所以我们必须定制一个兼容万国字符的编码表

【3】阶段三:一统天下(unicode)

  • unicode于1990年开始研发,1994年正式公布

(1)unicode的特点

  • 存在所有语言中的所有字符与数字的一一对应关系,即兼容万国字符
  • 与传统的字符编码的二进制数都有对应关系,详解如下
    • 很多地方或老的系统、应用软件仍会采用各种各样传统的编码,这是历史遗留问题。
    • 此处需要强调:软件是存放于硬盘的,而运行软件是要将软件加载到内存的,面对硬盘中存放的各种传统编码的软件,想让我们的计算机能够将它们全都正常运行而不出现乱码,内存中必须有一种兼容万国的编码,并且该编码需要与其他编码有相对应的映射/转换关系,这就是unicode的第二大特点产生的缘由

(2)字符的存储

  • 文本编辑器输入任何字符都是最新存在于内存中,是unicode编码的

    • 存放于硬盘中,则可以转换成任意其他编码,只要该编码可以支持相应的字符
  • 英文字符可以被ASCII识别

    • 英文字符--->unciode格式的数字--->ASCII格式的数字
  • 中文字符、英文字符可以被GBK识别

    • 中文字符、英文字符--->unicode格式的数字--->gbk格式的数字
  • 日文字符、英文字符可以被shift-JIS识别

    • 日文字符、英文字符--->unicode格式的数字--->shift-JIS格式的数字

img

【四】编码和解码

【1】编码(encode)

  • 由字符转换成内存中的unicode,以及由unicode转换成其他编码的过程,都称为编码encode
x = '上'  # 在python3在'上'被存成unicode
res = x.encode('utf-8')
print(res, type(res))  # unicode编码成了utf-8格式,而编码的结果为bytes类型,可以当作直接当作二进制去使用
# b'\xe4\xb8\x8a' <class 'bytes'>

# 只有英文字符和数字,要想编码的话,直接使用前缀b --- 字节对象没有encode方法
s = b'Dream123'
print(s, type(s))
# b'Dream123' <class 'bytes'>

img

【2】解码(decode)

  • 由内存中的unicode转换成字符,以及由其他编码转换成unicode的过程,都称为解码decode

  • 在诸多文件类型中,只有文本文件的内存是由字符组成的,因而文本文件的存取也涉及到字符编码的问题

x = b'\xe4\xb8\x8a'
res = x.decode('utf-8')
print(res, type(res))
# 上 <class 'str'>


s = b'Dream123'
res = s.decode('utf-8')
print(res, type(res))
# Dream123 <class 'str'>

img

【五】utf-8的诞生

【1】引言

  • 如果保存到硬盘的是GBK格式二进制,当初用户输入的字符只能是中文或英文

  • 同理如果保存到硬盘的是Shift_JIS格式二进制,当初用户输入的字符只能是日文或英文……

  • 如果我们输入的字符中包含多国字符,那么该如何处理?

  • 多国字符—√—>内存(unicode格式的二进制)——X—>硬盘(GBK格式的二进制)

  • 多国字符—√—>内存(unicode格式的二进制)——X—>硬盘(Shift_JIS格式的二进制)

  • 多国字符—√—>内存(unicode格式的二进制)——√—>硬盘(???格式的二进制)

【2】解决办法(utf-8)

  • 理论上是可以将内存中unicode格式的二进制直接存放于硬盘中的

    • 但由于unicode固定使用两个字节来存储一个字符
  • 如果多国字符中包含大量的英文字符时,使用unicode格式存放会额外占用一倍空间(英文字符其实只需要用一个字节存放即可)

  • 然而空间占用并不是最致命的问题

    • 最致命地是当我们由内存写入硬盘时会额外耗费一倍的时间
  • 所以将内存中的unicode二进制写入硬盘或者基于网络传输时必须将其转换成一种精简的格式

    • 这种格式即utf-8(全称Unicode Transformation Format,即unicode的转换格式)
    • 我们日常使用的字符编码都是utf8编码,但是,utf系列还有utf16 utf32... utf8mb4
    • utf8只能存储正常的字符,utf8mb4可以存储表情
  • 多国字符—√—>内存(unicode格式的二进制)——√—>硬盘(utf-8格式的二进制)

img

【3】为何在内存中不直接使用utf-8

  • utf-8是针对Unicode的可变长度字符编码:
    • 一个英文字符占1Bytes,
    • 一个中文字符占3Bytes,生僻字用更多的Bytes存储
  • unicode更像是一个过渡版本,
  • 我们新开发的软件或文件存入硬盘都采用utf-8格式
  • 等过去几十年,所有老编码的文件都淘汰掉之后,会出现一个令人开心的场景
  • 即硬盘里放的都是utf-8格式
  • 此时unicode便可以退出历史舞台
  • 内存里也改用utf-8,天下重新归于统一

【六】字符编码的应用

【1】学习字符编码的目的

  • 学习字符编码就是为了存取字符时不发生乱码问题

  • 内存中固定使用unicode无论输入任何字符都不会发生乱码

  • 我们能够修改的是存/取硬盘的编码方式,如果编码设置不正确将会出现乱码问题。

【2】乱码问题

  • 乱码问题分为两种:存乱了,读乱了

(1)存乱了

如果用户输入的内容中包含中文和日文字符,如果单纯以shift_JIS存,日文可以正常写入硬盘,而由于中文字符在shift_jis中没有找到对应关系而导致存乱了

(2)读乱了

  • 如果硬盘中的数据是shift_JIS格式存储的,采GBK格式读入内存就读乱了

(3)总结

  • 保证存的时候不乱
    • 在由内存写入硬盘时,必须将编码格式设置为支持所输入字符的编码格式
  • 保证存的时候不乱
    • 在由硬盘读入内存时,必须采用与写入硬盘时相同的编码格式

【七】Python解释器执行文件

【1】Python解释器执行文件的前两个阶段

  • 执行py文件的前两个阶段就是python解释器读文本文件的过程,与文本编辑读文本文件的前两个阶段没人任何区别

  • 要保证读不乱码,则必须将python解释器读文件时采用的编码方式设置为文件当初写入硬盘时的编码格式

  • 如果没有设置,python解释器则才用默认的编码方式,在python3中默认为utf-8,在python2中默认为ASCII

  • 我们可以通过指定文件头来修改默认的编码

  • 在文件首行加上

    # coding: 当初文件写入硬盘时采用的编码格式
    
  • 解释器会先用默认的编码方式读取文件的首行内容

    • 由于首行是纯英文组成,而任何编码方式都可以识别英文字符。

【3】python解释器执行文件的第三个阶段

  • 设置文件头的作用是保证运行python程序的前两个阶段不乱码

    • 经过前两个阶段后py文件的内容都会以unicode格式存放于内存中。
  • 在经历第三个阶段时开始识别python语法

    • 当遇到特定的语法name = '上'(代码本身也都全都是unicode格式存的)时
    • 需要申请内存空间来存储字符串'上'
    • 这就又涉及到应该以什么编码存储‘上’的问题了。
  • 在Python3中

  • 字符串类的值都是使用unicode格式来存储

  • 由于Python2的盛行是早于unicode的

    • 因此在Python2中是按照文件头指定的编码来存储字符串类型的值的(如果文件头中没有指定编码
    • 那么解释器会按照它自己默认的编码方式来存储‘上’)
    • 所以,这就有可能导致乱码问题
# coding:utf-8
# x的值为untf-8格式的二进制
x = '上'

# 打印操作是将x的值,即utf-8格式的二进制交给终端
# 当终端收到后发现并不是unicode(只有unicode才与字符有对应关系)
# 所以终端会执行操作:utf-8二进制---解码-->unicode格式的二进制
# 解码的过程终端会采用自己默认的编码
# 而在pycharm的终端默认编码为utf-8、windows下的cmd终端的默认编码为gbk
# 所以该打印操作在pycharm中显示正常,而在windows下的cmd中则乱码
print(x)
# 在windows下的cmd中运行效果如下
C:\Users\Administrator>python2 E:\aaa.py
涓
  • python2后推出了一种补救措施,就是在字符串类型前加u
    • 则会将字符串类型强制存储unicode
    • 这就与python3保持一致了
    • 对于unicode格式无论丢给任何终端进行打印,都可以直接对应字符不会出现乱码问题
# coding:utf-8
x = u'上' # 即便文件头为utf-8,x的值依然存成unicode

标签:编码,4.0,字符,Python,内存,unicode,格式,硬盘
From: https://www.cnblogs.com/dream-ze/p/17842409.html

相关文章

  • 【6.0】Python中级之异常处理
    【一】什么是异常异常是程序运行时可能发生的错误或意外情况。在Python中,异常是一种对象,表示程序执行期间发生的错误。当出现异常时,程序的正常流程会被中断,而是跳转到异常处理流程。【二】异常分类在Python中,异常分为两类:内建异常(Built-inExceptions):由Python内部定义......
  • 大白话说Python+Flask入门(三)
    写在前面今天状态很不好,我发现学这部分知识的时候,会出现溜号或者注意力无法集中的情况。我能想到的是,大概率是这部分知识,应该是超出了我现在的水平了,也就是说我存在知识断层了,整体感觉真的是一知半解。那有同学会问了,那你能说明白吗?我理解的肯定能呀,来往下看!Flask的使用1、......
  • Adobe Premiere Pro 2024 v24.0 Mac Intel芯片版下载
    软件介绍PremierePro2024是Adobe公司最新推出的一款视频编辑软件,它作为行业内最受欢迎的非线性编辑工具之一,为视频创作者提供了强大的剪辑、特效、调色和音频处理功能。PremierePro2024在保持一贯的高效、稳定和易用的基础上,进一步提升了用户体验和功能强度,使得视频制作更加......
  • Python批量求取Excel表格每一个4行内某列的最大值、最小值
      本文介绍基于Python语言,基于Excel表格文件内某一列的数据,计算这一列数据在每一个指定数量的行的范围内(例如每一个4行的范围内)的区间最大值的方法。  已知我们现有一个.csv格式的Excel表格文件,其中有一列数据,我们希望对其加以区间最大值的计算——即从这一列的数据部分(也就是......
  • 洛谷B2017 打印 ASCII 码(Python3)
    要点:1.Python的input()默认要换行,而在输入的时候即使只输了一个字符,也会被判定为输入两个字符。故此处要么只取字符串的第一位,要么在输入时用.strip()来删去首位字符,strip的介绍在这里2.Python中不能用强制类型转换来得到ASCII码,需要用到ord()函数。ord():括号内的字符的ASCI......
  • 洛谷B2016 浮点数向零舍入(Python3)
    要点:1.有正有负怎么办?正负分开写?如果只看数字部分,那取整的方式是一样的。所以我们可以先输出符号,把问题全都转化到非负数集中。2.如何取整?此处取整为向下取整。而强制类型转换把浮点数转化为整型数的时候是把小数部分全部去掉,而不是四舍五入,与题中取整方式相符,故可直......
  • python之numpy处理股票数据
    一概述Numpy是一个最重要的一个基于多维数组对象,即ndarray对象,该对象具有矢量算数运算能力和复杂的广播能力,可以执行一些科学计算。它的常用属性如下表所示:属性说明ndim数组的维度,如一维、二维、三维等shape数组的形状,如一个5行4列的数组,它的shape属性为(5,4)size数组元素的总个数......
  • 如何使用 Python 爬取天气预报网站的内容,并通过邮件发送爬取结果到指定邮箱地址
    本文是作者参加腾讯云社区选题互换赛解答的一道题目。题目为:如何使用Python爬取网页(例如天气,每日问好等等)出题者的动机是:每天早上要和妹子说早安,想要做个定时任务,每天早上能自动爬取天气,发送天气问好邮件,希望大神支招。面对这个题目,我们可以将其拆解成若干个小任务:使用Pytho......
  • 使用 ChatGPT 帮助小学生编程入门系列之二:使用 Python 编程发送电子邮件
    本系列前一篇文章,我们已经介绍了如何使用Python编写一段代码,将搜索引擎上找到的天气预报网站上的信息,读取到本地:使用ChatGPT帮助小学生编程入门系列之一:Python编程读取和解析天气预报网页上的数据本文我们再进一步,目标是把一段文本,通过Python发送到指定的邮箱去。学会......
  • python踩坑记录之import和module
    1.问题重现最近开发时需要将一个别人的python项目作为submodule引入,调用的时候遇到了奇怪的问题,最后定位到问题是import导致的。首先对问题做一个说明。项目结构如下:Project/main.pysubmodule/__init__.pyhandler.pytools.py导致问题的......