python基础之字符编码

阅读目录

一 了解字符编码的知识储备

一 计算机基础知识

 

二 文本编辑器存取文件的原理(nodepad++,pycharm,word)

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

三 python解释器执行py文件的原理 ,例如python test.py

复制代码
#第一阶段:python解释器启动,此时就相当于启动了一个文本编辑器#第二阶段:python解释器相当于文本编辑器,去打开test.py文件,从硬盘上将test.py的文件内容读入到内存中(小复习:pyhon的解释性,决定了解释器只关心文件内容,不关心文件后缀名)#第三阶段:python解释器解释执行刚刚加载到内存中test.py的代码( ps:在该阶段,即真正执行代码时,才会识别python的语法,执行文件内代码,当执行到name="egon"时,会开辟内存空间存放字符串"egon")
复制代码

四 总结python解释器与文件本编辑的异同

#1、相同点:python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样#2、不同点:文本编辑器将文件内容读入内存后,是为了显示或者编辑,根本不去理会python的语法,而python解释器将文件内容读入内存后,可不是为了给你瞅一眼python代码写的啥,而是为了执行python代码、会识别python语法。

二 字符编码介绍

一 什么是字符编码

复制代码
  计算机要想工作必须通电,即用‘电’驱使计算机干活,也就是说‘电’的特性决定了计算机的特性。电的特性即高低电平(人类从逻辑上将二进制数1对应高电平,二进制数0对应低电平),关于磁盘的磁特性也是同样的道理。结论:计算机只认识数字很明显,我们平时在使用计算机时,用的都是人类能读懂的字符(用高级语言编程的结果也无非是在文件内写了一堆字符),如何能让计算机读懂人类的字符?必须经过一个过程:#字符--------(翻译过程)------->数字 #这个过程实际就是一个字符如何对应一个特定数字的标准,这个标准称之为字符编码
复制代码

二 以下两个场景下涉及到字符编码的问题:

#1、一个python文件中的内容是由一堆字符组成的,存取均涉及到字符编码问题(python文件并未执行,前两个阶段均属于该范畴)#2、python中的数据类型字符串是由一串字符组成的(python文件执行时,即第三个阶段)

三 字符编码的发展史与分类(了解)

计算机由美国人发明,最早的字符编码为ASCII,只规定了英文字母数字和一些特殊字符与数字的对应关系。最多只能用 8 位来表示(一个字节),即:2**8 = 256,所以,ASCII码最多只能表示 256 个符号

当然我们编程语言都用英文没问题,ASCII够用,但是在处理数据时,不同的国家有不同的语言,日本人会在自己的程序中加入日文,中国人会加入中文。

而要表示中文,单拿一个字节表表示一个汉子,是不可能表达完的(连小学生都认识两千多个汉字),解决方法只有一个,就是一个字节用>8位2进制代表,位数越多,代表的变化就多,这样,就可以尽可能多的表达出不通的汉字

所以中国人规定了自己的标准gb2312编码,规定了包含中文在内的字符->数字的对应关系。

日本人规定了自己的Shift_JIS编码

韩国人规定了自己的Euc-kr编码(另外,韩国人说,计算机是他们发明的,要求世界统一用韩国编码,但世界人民没有搭理他们)

 

这时候问题出现了,精通18国语言的小周同学谦虚的用8国语言写了一篇文档,那么这篇文档,按照哪国的标准,都会出现乱码(因为此刻的各种标准都只是规定了自己国家的文字在内的字符跟数字的对应关系,如果单纯采用一种国家的编码格式,那么其余国家语言的文字在解析时就会出现乱码)

所以迫切需要一个世界的标准(能包含全世界的语言)于是unicode应运而生(韩国人表示不服,然后没有什么卵用)

ascii用1个字节(8位二进制)代表一个字符

unicode常用2个字节(16位二进制)代表一个字符,生僻字需要用4个字节

例:

字母x,用ascii表示是十进制的120,二进制0111 1000

汉字已经超出了ASCII编码的范围,用Unicode编码是十进制的20013,二进制的01001110 00101101

字母x,用unicode表示二进制0000 0000 0111 1000,所以unicode兼容ascii,也兼容万国,是世界的标准

 

这时候乱码问题消失了,所有的文档我们都使用但是新问题出现了,如果我们的文档通篇都是英文,你用unicode会比ascii耗费多一倍的空间,在存储和传输上十分的低效

本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间:

字符ASCIIUnicodeUTF-8
A0100000100000000 0100000101000001
x01001110 0010110111100100 10111000 10101101

从上面的表格还可以发现,UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。

四 总结字符编码的发展可分为三个阶段(重要)

 !!!重点!!!

三 字符编码应用之文件编辑器

3.1 文本编辑器之nodpad++

 

 !!!乱码分析!!! 

3.2 文本编辑器之pycharm

以utf-8格式打开(选择reload)

 pycharm中:reload与convert的区别

3.3 文本编辑器之python解释器

复制代码
文件test.py以gbk格式保存,内容为:x='林'无论是python2 test.py还是python3 test.py都会报错(因为python2默认ascii,python3默认utf-8)除非在文件开头指定#coding:gbk
复制代码

3.4 总结

!!!总结非常重要的两点!!!

#1、保证不乱吗的核心法则就是,字符按照什么标准而编码的,就要按照什么标准解码,此处的标准指的就是字符编码#2、在内存中写的所有字符,一视同仁,都是unicode编码,比如我们打开编辑器,输入一个“你”,我们并不能说“你”就是一个汉字,此时它仅仅只是一个符号,该符号可能很多国家都在使用,根据我们使用的输入法不同这个字的样式可能也不太一样。只有在我们往硬盘保存或者基于网络传输时,才能确定”你“到底是一个汉字,还是一个日本字,这就是unicode转换成其他编码格式的过程了

                  unicode----->encode-------->utf-8

                  utf-8-------->decode---------->unicode

#补充:浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器如果服务端encode的编码格式是utf-8, 客户端内存中收到的也是utf-8编码的结果。

 

四 字符编码应用之python

4.1 执行python程序的三个阶段

python test.py   (我再强调一遍,执行test.py的第一步,一定是先将文件内容读入到内存中)

test.py文件内容以gbk格式保存的,内容为:

阶段一:启动python解释器

阶段二:python解释器此时就是一个文本编辑器,负责打开文件test.py,即从硬盘中读取test.py的内容到内存中

此时,python解释器会读取test.py的第一行内容,#coding:utf-8,来决定以什么编码格式来读入内存,这一行就是来设定python解释器这个软件的编码使用的编码格式这个编码,可以用sys.getdefaultencoding()查看,如果不在python文件指定头信息#-*-coding:utf-8-*-,那就使用默认的python2中默认使用ascii,python3中默认使用utf-8 

 

改正:在test.py指定文件头,字符编码一定要为gbk,

#coding:gbk
你好啊

阶段三:读取已经加载到内存的代码(unicode编码格式),然后执行,执行过程中可能会开辟新的内存空间,比如x="egon"

复制代码
内存的编码使用unicode,不代表内存中全都是unicode,在程序执行之前,内存中确实都是unicode,比如从文件中读取了一行x="egon",其中的x,等号,引号,地位都一样,都是普通字符而已,都是以unicode的格式存放于内存中的但是程序在执行过程中,会申请内存(与程序代码所存在的内存是俩个空间)用来存放python的数据类型的值,而python的字符串类型又涉及到了字符的概念比如x="egon",会被python解释器识别为字符串,会申请内存空间来存放字符串类型的值,至于该字符串类型的值被识别成何种编码存放,这就与python解释器的有关了,而python2与python3的字符串类型又有所不同。 
复制代码

4.2 python2与python3字符串类型的区别

一 在python2中有两种字符串类型str和unicode

str类型

当python解释器执行到产生字符串的代码时(例如x='上'),会申请新的内存地址,然后将'上'编码成文件开头指定的编码格式

要想看x在内存中的真实格式,可以将其放入列表中再打印,而不要直接打印,因为直接print()会自动转换编码,这一点我们稍后再说。

#coding:gbk
x='上'
y='下'
print([x,y]) #['\xc9\xcf', '\xcf\xc2']
#\x代表16进制,此处是c9cf总共4位16进制数,一个16进制四4个比特位,4个16进制数则是16个比特位,即2个Bytes,这就证明了按照gbk编码中文用2Bytes
print(type(x),type(y)) #(<type 'str'>, <type 'str'>)

理解字符编码的关键!!!

内存中的数据通常用16进制表示,2位16进制数据代表一个字节,如\xc9,代表两位16进制,一个字节

gbk存中文需要2个bytes,而存英文则需要1个bytes,它是如何做到的???!!!

gbk会在每个bytes,即8位bit的第一个位作为标志位,标志位为1则表示是中文字符,如果标志位为0则表示为英文字符

x=‘你a好’
转成gbk格式二进制位
8bit+8bit+8bit+8bit+8bit=(1+7bit)+(1+7bit)+(0+7bit)+(1+7bit)+(1+7bit)

这样计算机按照从左往右的顺序读:

#连续读到前两个括号内的首位标志位均为1,则构成一个中午字符:你#读到第三个括号的首位标志为0,则该8bit代表一个英文字符:a#连续读到后两个括号内的首位标志位均为1,则构成一个中午字符:好

也就是说,每个Bytes留给我们用来存真正值的有效位数只有7位,而在unicode表中存放的只是这有效的7位,至于首位的标志位与具体的编码有关,即在unicode中表示gbk的方式为:

(7bit)+(7bit)+(7bit)+(7bit)+(7bit)

 

按照上图翻译的结果,我们可以去unicode关于汉字的对应关系中去查:链接:https://pan.baidu.com/s/1dEV3RYp

 

可以看到“”上“”对应的gbk(G0代表的是gbk)编码就为494F,即我们得出的结果,而上对应的unicode编码为4E0A,我们可以将gbk-->decode-->unicode

#coding:gbk
x='上'.decode('gbk')
y='下'.decode('gbk')
print([x,y]) #[u'\u4e0a', u'\u4e0b']

unicode类型

当python解释器执行到产生字符串的代码时(例如s=u'林'),会申请新的内存地址,然后将'林'以unicode的格式存放到新的内存空间中,所以s只能encode,不能decode

#coding:gbk
x=u'上' #等同于 x='上'.decode('gbk')
y=u'下' #等同于 y='下'.decode('gbk')
print([x,y]) #[u'\u4e0a', u'\u4e0b']
print(type(x),type(y)) #(<type 'unicode'>, <type 'unicode'>)

打印到终端

对于print需要特别说明的是:

当程序执行时,比如

x='上' #gbk下,字符串存放为\xc9\xcf

print(x) #这一步是将x指向的那块新的内存空间(非代码所在的内存空间)中的内存,打印到终端,按理说应该是存的什么就打印什么,但打印\xc9\xcf,对一些不熟知python编码的程序员,立马就懵逼了,所以龟叔自作主张,在print(x)时,使用终端的编码格式,将内存中的\xc9\xcf转成字符显示,此时就需要终端编码必须为gbk,否则无法正常显示原内容:上

对于unicode格式的数据来说,无论怎么打印,都不会乱码

unicode这么好,不会乱码,那python2为何还那么别扭,搞一个str出来呢?python诞生之时,unicode并未像今天这样普及,很明显,好的东西你能看得见,龟叔早就看见了,龟叔在python3中将str直接存成unicode,我们定义一个str,无需加u前缀,就是一个unicode,屌不屌?

 

二 在python3 中也有两种字符串类型str和bytes

str是unicode

复制代码
#coding:gbk
x='上' #当程序执行时,无需加u,'上'也会被以unicode形式保存新的内存空间中,print(type(x)) #<class 'str'>#x可以直接encode成任意编码格式
print(x.encode('gbk')) #b'\xc9\xcf'
print(type(x.encode('gbk'))) #<class 'bytes'>
复制代码

很重要的一点是:看到python3中x.encode('gbk') 的结果\xc9\xcf正是python2中的str类型的值,而在python3是bytes类型,在python2中则是str类型

于是我有一个大胆的推测:python2中的str类型就是python3的bytes类型,于是我查看python2的str()源码,发现

转载于:https://www.cnblogs.com/iamjianghao/p/8028890.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/278146.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# WinForm开发系列 - DataGridView

1.DataGridView实现课程表 testcontrol.rar 2.DataGridView二维表头及单元格合并 DataGridView单元格合并和二维表头.rar myMultiColHeaderDgv.rar 3.DataGridView单元格显示GIF图片 gifanimationindatagrid.rar 4.自定义显示DataGridView列(行头显示行号与图标,同一单元格显示…

ruby语法_Ruby函数(方法)语法

ruby语法The Ruby language makes it easy to create functions. Ruby语言使创建函数变得容易。 Function Syntax 功能语法 def functionname(variable) return <value>end def functionname(variable)return <值>结束Examples 例子 Your function can compute …

pageadmin CMS网站建设教程:站点添加自定义字段

首先看看pagedmin默认的站点设置都有什么&#xff0c;如下图&#xff1a; 这里只有一些最基本的参数设置&#xff0c;用过3.0版本或用过其他公司开发的cms的用户应该有这种体验&#xff0c;在站点设置中可以设置logo图片&#xff0c;备案号&#xff0c;底部内容等等。 那么为什…

如何将世界时钟和时区小部件添加到您的iPhone

When you work remotely or have friends and family who live in another country, it’s important to know what time it is across time zones. A world clock (or time zone) widget on your iPhone’s Home screen makes this much easier. 当您远程工作或有家人和朋友居…

小程序视频截gif_3个简单的应用程序,可让您深入视频和GIF

小程序视频截gifDeepfakes make it possible to manipulate videos and GIFs. The technology has become so easy to use, you can now create deepfakes right on your phone. That’s right—you can now easily insert yourself into a meme. 借助Deepfake &#xff0c;可以…

【AtCoder】ARC095 E - Symmetric Grid 模拟

【题目】E - Symmetric Grid 【题意】给定n*m的小写字母矩阵&#xff0c;求是否能通过若干行互换和列互换使得矩阵中心对称。n,m<12。 【算法】模拟 【题解】首先行列操作独立&#xff0c;如果已确定行操作&#xff0c;那么两个在对称位置的列要满足条件必须其中一列反转后和…

如何使用Google TV设置Chromecast

Justin Duino贾斯汀杜伊诺(Justin Duino)Google changed up its streaming platform with the release of the Chromecast with Google TV. Instead of being a Cast-only device like Chromecasts before it, Google’s latest dongle runs the successor of Android TV. If y…

scala 方法、函数定义小结

2019独角兽企业重金招聘Python工程师标准>>> package scalapackage.testmethod/*** Created by Germmy on 2018/4/15.*/ object TesMethod {def main(args: Array[String]) {//定义方法的一种方法,高阶函数的一种定义方法def m1(x:Int)(y:Int)x*yval resm1(3)(4)pri…

ipad和iphone切图_如何在iPhone和iPad上密码保护照片

ipad和iphone切图Sometimes, you need to protect your iPhone or iPad photos from prying eyes that might also have access to your device. Unfortunately, Apple doesn’t provide an obvious, secure way to do this. However, there’s a work-around thanks to the No…

Java高级篇(二)——网络通信

网络编程是每个开发人员工具箱中的核心部分&#xff0c;我们在学习了诸多Java的知识后&#xff0c;也将步入几个大的方向&#xff0c;Java网络编程就是其中之一。 如今强调网络的程序不比涉及网络的更多。除了经典的应用程序&#xff0c;如电子邮件、Web浏览器和远程登陆外&…

Jerry和您聊聊Chrome开发者工具

2019独角兽企业重金招聘Python工程师标准>>> Chrome开发者工具是Jerry日常工作使用的三大调试器之一。虽然工具名称前面带了个"开发者", 但是它对非开发人员仍然有用。不信&#xff1f; 用Chrome打开我们常用的网站&#xff0c;按F12&#xff0c;在Consol…

win2008R2管理员密码修改文档

场景&#xff1a;忘记了win2008R2服务器的管理员密码。解决办法&#xff1a;1、 制作一个U盘启动盘&#xff1a;2、 系统通过U盘启动进入WINpe系统3、 在知道Win2008安装位置的情况下&#xff1b;查找C:\windows\system32\osk.exe 将osk.exe文件修改为&#xff1a;osk.exe.bat&…

第四周

7-2 选择法排序 &#xff08;20 分) 本题要求将给定的n个整数从大到小排序后输出。 输入格式&#xff1a; 输入第一行给出一个不超过10的正整数n。第二行给出n个整数&#xff0c;其间以空格分隔。 输出格式&#xff1a; 在一行中输出从大到小有序的数列&#xff0c;相邻数字间有…

来谈谈JAVA面向对象 - 鲁班即将五杀,大乔送他回家??

开发IDE为Eclipse或者MyEclipse。 首先&#xff0c;如果我们使用面向过程的思维来解决这个问题&#xff0c;就是第一步做什么&#xff0c;第二步做什么&#xff1f; 鲁班即将五杀&#xff0c;大乔送他回家 这个现象可以简单地拆分为两步&#xff0c;代码大概是这个样子的: publ…

Microsoft Teams的Outgoing Webhook开发入门

Microsoft Teams的应用程序有几种形式&#xff1a; TabsBotsConnectorsMessaging extensionsActivity feed integrationsOutgoing web hooks 这篇我们主要介绍如何使用 ASP.NET Core来开发最简单的Outgoing web hook。 什么是outgoing webhook Outgoing webhooks allow you t…

0418 jQuery笔记(添加事件、each、prop、$(this))

1.添加点击事件、each、prop、$(this) 1 //全选框的被动操作2 //定义一个标志保存最终状态3 var flag false;4 //为每一个选择框添加点击事件&#xff0c;数组.click()5 $(.chex).click(function(){6 //遍历数组&#xff0c;数组.each()7 …

使用dotnet template快速开发Microsoft Teams Outgoing Web Hook

在上一篇文章中&#xff0c;我们一步步从无到有在Microsoft Teams中开发了一个简单的Outgoing Webhook&#xff0c;并和我们本地的Web API应用程序产生交互&#xff0c;总结起来的步骤大概如下&#xff1a; 导航到“团队” Tab页&#xff0c; 选中需要建立的Channel, 选中“应…

Microsoft Teams:删除成员账户其历史聊天会发生什么?

介绍&#xff1a; 此博客文章的目的是演示从Office 365删除用户的账号后&#xff0c;此用户在Microsoft Teams群聊和私聊中的历史聊天记录会发生什么改变。 以下是Microsoft Teams聊天对话&#xff0c;其中Adele和其他团队成员正在参与对话&#xff1a; 此外, Adele和Mega还在…

Microsoft Teams:团队Owner离开公司后,我们该怎么做?

您是否曾在这么一个团队里&#xff0c;该团队唯一有Owner权限的人离开了公司&#xff1f;不幸的是,如果这个人不再在公司里&#xff0c;您可能觉得没有办法让其他团队成员再成为team的owner。我有一个简单易用的解决方案&#xff0c;但您需要成为Office 365租户的Admin或联系你…

python网络编程-socket编程

一、服务端和客户端 BS架构 &#xff08;腾讯通软件&#xff1a;serverclient&#xff09; CS架构 &#xff08;web网站&#xff09; C/S架构与socket的关系&#xff1a; 我们学习socket就是为了完成C/S架构的开发 二、OSI七层模型 互联网协议按照功能不同分为osi七层或tcp/ip五…