1. 问题起源

我们在学习Python的过程中,可能会经常遇到下方这样的编码问题。有时候我们需要选择gbk,有时候需要选择utf-8。你以为这样就完了吗?碰到的还有gb2312gb18030等各种奇奇怪怪的编码。那么,编码的起源究竟是怎样的呢?我们今天就用 “讲故事” 的方式,带你认识一下它。

2. 黄同学给你讲故事

1)烽火士兵的故事

在正式讲故事之前,我们先来看一下下方这张图,我们暂且称其为 《烽火士兵》 的故事,那么这个故事究竟是怎么与编码问题扯上联系的呢?接着听我讲故事。


这一串数字,从右朝左看。
点燃第1根,代表有一个士兵,点燃第2根,代表有二个士兵。那么也就是说,点燃2个烽火,最多可以表示三个士兵。梳理一下逻辑,1个烽火都不点,表示有零个士兵;只点燃第1个烽火,就表示有一个士兵;在点燃第2个烽火的时候,熄灭第1个烽火,就表示有二个士兵;同时点燃2个烽火,就表示有三个士兵。

综上所述:2根烽火,可以表示:0、1、2、3个士兵,即1+2。3根烽火,可以表示:0、1、2、3、4、5、6、7个士兵,即1+2+4。依此类推下去…

通过上面的叙述,你可能已经发现了,这不就是类似计算机里面的二进制数字吗?只有0和1,0表示熄灭烽火,1表示点燃烽火。对应到计算机中就是,0表示关,1表示开。下面黄同学就带着大家说一下 “计算机中的0和1”

计算机的底层是电路,只认识0和1,就是你初中物理中所谓的 “电路”,0表示关,1表示开,没有别的玩意儿。但是你想呀,一个电路只有0和1的话,怎么展示出这绚丽多彩的世界呢?因此,聪明的老外,把日常所用的文字和符号,编码成0101010…类型,这样电脑就能够表示文字了。所以,先记住一个关键语:“用什么编码,就用什么解码”

由于,计算机是由美国人发明的。因此,最早的计算机编码:ASCII码(也是服务于美国人的),里面只有美国人日常所用的26个英文字母、数字、标点等常用字符,所以,最早的计算机也只有英文、数字、标点等特殊字符。不要惊叹为啥只有美国人常用的英文字母和符号,因为老美当时就没有想过计算机会迅速在全世界普及开来,谁也不能提前预知未来。

接着我们来说说最早的计算机编码: ASCII码。ASCII码占8个比特位,也就是一个字节,其中最前面一个位是扩展位,都是0,为了日后扩展所用,其余位置不是0就是1。这是由于计算机对数字7不敏感,熟悉2、4、8、16、32…等数字,所以扩展了一位,成了8位。那么根据排列组合的知识,ASCII码可以表示2^7=128个码位,即可以表示128种不同的符号,其实这些符号已经够美国人使用了。这就是当时最早的计算机编码(ASCII码),这就是当时老美的打算。

2)计算机在中国的发展

随着计算机在世界各地的发展,我们发现原有的码位已经不够存放多国的文字和符号了,为了讲清楚这件事儿,我们以计算机在中国的发展为例,进行说明。

通过前面的叙述,我们已经知道最早的字符编码ASCII码中,并没有中文,但是随着计算机在中国的普及,我们必要得让计算机中能够表示中文呀,怎么办呢?基于此:中国北大方正团队,发明了gbk编码。但是这些字符肯定不能直接往ASCII码里面放,因为ASCII只有8位,最多才有2 ^ 8=256个空位,存放九万多汉字,显然不可能(就连中文中常用的3000汉字,也存放不了)。所以在gbk中,汉字用2个字节表示,变成了ASCII码中字节长度的2倍,即gbk占16位,共2 ^ 16=65536个空位,这个对于存放常用汉字,多得多,但是,仍然不能将所有汉字存放进去,谁让中华文化源远流长,博大精深呢。

说到gbk,就不得不说它的兄弟姐妹了(如图所示),其实它们是一个系列,都是由于当时的需要,逐步衍生出来的,这三种不同的编码都是向上兼容的。可以看出:GB18030表示的字符数最多,这也就是为什么有时候使用Python读取Excel表时,使用GB2312和GBK都不行,而必须使用GB18030的原因了。

3)计算机如何兼容多国语言

计算机不仅在中国发展开来,其实计算机是在全世界迅速发展开来。如果说中国有自己独有的GBK编码,那么韩国、日本肯定也有它们自己独有的编码。但是当今是 “经济全球化” 的时代,任何一个国家都不可能的单独发展,假如你有一个国际合作的业务,我们在中国写的代码,要是想拿到国外去用,出现乱码,这样多尴尬?那么这个问题最终是怎么解决的呢?

为此,美国人又发明了一个叫做 “Unicode” 的东西,又叫做 “万国码”。其实完全可以见名知意,万国码万国码,肯定是为了包含全世界麦!那么什么是万国码呢?接着听黄同学给你讲。

我们知道:计算机扩展一般是成倍增加的,要么是1个字节、2个字节、4个字节…。最开始的Unicode,又叫ucs-2,ASCII存储采用1个字节,因此ucs-2采用2个字节进行存储,最多有2 ^ 16 =65536 个空位,这样仍然无法兼容全世界的字符。于是ucs-4产生了,存储采用4个字节,共2 ^ 32=4亿多个空位。但是据统计,全世界文字、数字、符号信息加起来也就23万,对于4亿多空间来说,ucs-4简直太浪费空间了,这个对于文件传输来说,及其浪费流量。


考虑到节省空间,在Unicode基础上,我们又发明了utf-8,一种可变长的Unicode字符编码。Utf-8,对于英文来说,采用ASCII码占位方式,占8位,即1个字节;存放欧洲文字时,占16位,即2个字节;存放中文时,占24位,即3个字节。虽然对于中文来说很浪费空间,但是为了能把全世界文字都统一起来,又为了节省空间,采用这种方式,已经很好了(因为毕竟不可能做到面面俱到,谁让中国字符最多,会吃亏一点)。

3. 编码知识总结

1)字符编码发展史

2)以小写字母a为例,说明字符编码

3)带着大家写写代码,认识一下字符编码

① 关于Python2和Python3的区别

在Python2中,默认字符编码是ASCII码,因此在Python2中写中文,首行一般都会加上-- coding:utf-8 --,看了这篇文章,我想你对这个东西已经有了一个清楚的认识。但是Python2现在已经停止更新了,我们了解即可,不用太关注。

对于Python3.x来说,默认字符编码是utf-8,而utf-8是Unicode的扩展集。即Python3.x中默认所有的字符都是Unicode。说白点,我们在Python3.x中随便写点啥,编码就是Unicode编码。

对比Python2和Python3:

# 在Python2中如果要表示Unicode编码,应该这样写。
my_name = u"黄伟"
# 在Python3中如果要表示Unicode编码,应该这样写。
my_name = "黄伟"

说到这里,我们可以下一个结论:不同编码之间的转换,都要经过一个Unicode。

② encode编码和decode解码

>>> name1 = "我是你们的teacher老师"
>>> name2 = "你们是我的student学生"
>>> # 将name1编码为“utf-8”
>>> name1_encode = name1.encode("utf-8")
>>> name1_encode
b'\xe6\x88\x91\xe6\x98\xaf\xe4\xbd\xa0\xe4\xbb\xac\xe7\x9a\x84teacher\xe8\x80\x81\xe5\xb8\x88'
>>> # 将name1_encode解码还原
>>> name1_encode.decode("utf-8")
'我是你们的teacher老师'
---------------------------------------------------------
>>> # 将name2编码为“gbk”
>>> name2_encode = name2.encode("gbk")
>>> name2_encode
b'\xc4\xe3\xc3\xc7\xca\xc7\xce\xd2\xb5\xc4student\xd1\xa7\xc9\xfa'
>>> # 将name2_encode解码还原
>>> name2_encode.decode("gbk")
'你们是我的student学生'
-------------------------------------------------
>>> # name1_encode此时是“utf-8”编码,如果用“gbk”解码,会出现什么?
>>> name1_encode.decode("gbk")
'鎴戞槸浣犱滑鐨則eacher鑰佸笀'
# 上面就是我们常说的乱码、乱码、乱码!

代码分析: 从代码中可以看出,如果是utf-8编码,每个中文字符就是3个字节存储。如果是gbk编码,每个中文字符就是2个字节存储。

用“讲故事”的方式,带你认识Python编码问题起源和发展!相关推荐

  1. python怎么认识_用“讲故事”的方式,带你认识Python编码问题的起源和发展!

    问题起源 我们在学习Python的过程中,可能会经常遇到下方这样的编码问题.有时候我们需要选择gbk,有时候需要选择utf-8.你以为这样就完了吗?我们碰到的还有gb2312,gb18030等各种奇奇 ...

  2. 全网讲解 “Python编码“ 最全的教程了

    编码问题一直是Python学习者一个头疼的问题,经常看到的gbk.utf-8,这都是啥玩意儿?因此,今天我正好出一期教程,好好讲述一下编码的起源和发展. 问题起源 我们在学习Python的过程中,可能 ...

  3. 带你学python基础:列表List

    在上一节中带你学python基础:变量和基本数据类型中,已经讲到了列表List如何创建和简单的使用,在这一节中,我们将更加细致入微的了解一下List更多的操作! 一.列表是什么? 列表是什么就是:一个 ...

  4. python基础入门(Peak带你学python)

    带你学python Peak带你学python 基础语法知识 print函数 转义字符 进制转换 保留字和标识符 变量 数据类型 数据类型转换 注释 input函数 运算符 运算符优先级 布尔值 if ...

  5. python回调接口_三个案例带你了解python回调函数

    原标题:三个案例带你了解python回调函数 回调函数: 把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数.回调函数不是由该函数的实现方直接调用 ...

  6. np合并 python_这15个tips,带你领略 Python 的简洁和优雅

    本文通过15个具体的例子,带你领略 Python 的简洁和优雅. 下文中'P'即表示'Pythonic',很 Python 的写法,'NP'也就是相反,不是很'Pythonic'的写法. 1.为多个变 ...

  7. 带你自学Python系列(七):Python列表复制陷阱

    ↑ 点击上方[计算机视觉联盟]关注我们 今天是小编持续更新关于Python的知识总结以及Python实践项目应用的第7天,带你利用零碎时间自学最受欢迎的编程语言之一Python语言.你和小编一起打卡了 ...

  8. 25个关键技术点,带你熟悉Python

    摘要:本文收纳了Python学习者经常使用的库和包,并介绍了Python使用中热门的问题. 01.Python 简介 什么是 Python 一种面向对象的高级动态可解释型脚本语言. Python 解释 ...

  9. 带你了解Python炫酷的颜色输出与进度条打印

    Python风骚的打印 大家平时在Linux/Windows下安装软件时,经常会出现进度条和百分比的提示,Python是否能实现这样的打印?安装过程中,经常会看到很多带颜色的安装说明,我们在pytho ...

  10. 为什么一个程序中变量只能定义一次_#带你学Python# 从简单程序出发理解Python基本语法

    欢迎回来. 通过上一篇文章,我们第一次触摸了Python,学会了如何用各种不同的方式运行Python的解释器.也介绍了很多工具和开发环境,是不是跃跃欲试了? 到这里,别的python教程就会从数据类型 ...

最新文章

  1. Linux基础:Shell脚本学习
  2. 学习使用Bing Maps Silverlight Control(一):准备和新建
  3. html细边框表格代码,html中表格细边框的四种实现及其比较.doc
  4. angular中的href=unsafe:我该怎么摆脱你的溺爱!!
  5. 论文浅尝 | 使用预训练深度模型和迁移学习方法的端到端模糊实体匹配
  6. 数学通大道,算法合自然?
  7. python内核死亡的原因_Python xgboost:内核死亡
  8. “出道” 5 年采用率达 78%,Kubernetes 为何如此成功?
  9. rosdep init 和rosdep update的解决方法,亲测有效
  10. 关于elasticsearch 基础篇(搜索文档)
  11. 负载均衡策略_高负荷小区负载均衡策略建议
  12. 电源完整性之Cadence Sigrity Power DC_电热协同仿真
  13. 用matlab机器人工具箱对SCARA机器人建模
  14. 【2018提高测试】飘雪圣域 【连通性+可持久化线段树 / 离线+权值线段树】 (详解)
  15. Android Provision(开机向导setupwizard程序)
  16. 设置ubuntu1920*1080分辨率
  17. 经典文献阅读之--PON
  18. DRC(Data Replicate Center)
  19. 桂林理工大学专科计算机专业在哪个校区,桂林理工大学专科在哪个校区
  20. 简易扩音机设计1——麦克风篇

热门文章

  1. Unity粒子特效系列-毒液喷射预制体做好了,unitypackage包直接用 - 上
  2. 宽度学习(一):宽度学习体系:有效和高效的无需深度架构的增量学习系统
  3. Ubuntu最佳字体推荐
  4. js 封装websocket (包括心跳检测,断线重连等)
  5. jquery video全屏_帮助你生成全屏视频背景的超棒jQuery插件 BigVideo.js
  6. java调用考勤机_zkteco iface702 中控考勤机java开发步骤一---连接考勤机
  7. 防止 跨站请求伪造(CSRF)
  8. 13.56MHZ刷卡芯片CI521兼容cv520/ci520支持A卡B卡MIFARE协议
  9. python考勤系统_python – 使用Django的考勤系统
  10. keyshot怎么批量渲染_怎样用keyshot 5.0快速渲染出高质量图