Python 编译器与解释器

Python的环境我们已经搭建好了,可以开始学习基础知识了。但是,在此之前,还要先说说编译器与解释器相关的内容。

如果这部分内容,让你觉得难以理解或不能完全明白,可以暂时跳过,等以后再回过头来重新读一遍。

一、数据的表示方式

我们都知道,现实生活中,数字的表示方式有很多种,常见的有二进制、八进制、十进制和十六进制。十进制我们都很熟悉,加法口诀表我们都背过,主要是使用0~9,这10个阿拉伯数字来构建整个十进制的体系,其中最核心的法则是“逢十进一”,借位则是“借一当十”。那么为什么全世界不管什么国家,什么历史,什么文化水平基本都是用十进制作为基本进制呢?是因为我们人有10个手指头,掰起来最方便!我们对十进制有着天然的友好度。

那么对于计算机呢?计算机不是人,没有10个手指头可以掰,所以它用不了十进制。那么它用几进制?二进制!二进制是用0和1两个数码来表示的数,也就是形如010101010的样子。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”。

为什么计算机要使用二进制作为自己的机器语言也就是数据的表示方式呢?因为计算机最小的计算单元是根据开关状态高低电平来确定的,它只有开和关,高和低的概念,换成数学就是0和1的两种。同样的,在物理存储方面,硬盘的磁道只能区分打孔和未打孔的状态,也是0和1两种。同时二进制便于进行加、减运算和计数编码。二进制与十进制数易于互相转换。二进制便于逻辑判断(是或非),逻辑判断通常也是两种状态,这和二进制很搭配。二进制表示数据还具有抗干扰能力强,可靠性高的特点,因为当受到一定程度的电磁干扰时,只要可以分辨出它是高电平还是低电平,至于高多少或低多少并不重要,就能区分0和1,这在网络信号中,就是天生自带抗干扰能力。

但是,在人机交流上,二进位制有致命的弱点,数字的书写特别冗长,并且没有人类可读性!例如,十进位制的100000写成二进制就是11000011010100000,长了好几倍,而且你能从一个这么长的二进制数里读出它的十进制数是多少吗?

计算机不能独立存在,目前也无法自我创造,不管是输入还是输出,它的一切都必须和人交流。那么问题来了,人类只能读10进制和英语、汉语等,可计算机只会010101,至于英语、汉语对它而言更是天书。那么我们是怎么和计算机交流的呢?怎么将我们的英语或者汉语编码成计算机能够识别的1010101呢?

二、 编程语言发展历程

1. 打孔纸条

我们已经知道了计算机只懂机器语言,也就是二进制的数据表示方式,任何对它的操作和编码,最终都要统一到这上面来,然而这是一个悲伤的故事。

起初,为了让计算机按我们的想法工作,程序员不得不编写计算机可以读懂看明白直接执行的机器码,也就是01010101的样子,打孔字条就是这么干的。用打没打孔来代表0和1。OK,计算机没问题,它能无障碍阅读,可程序员就难受了。拍脑袋也能想得到这里面的问题。容易出错,效率低,编写困难,维护困难。可能就是个简单的打印“hello world”,也许就需要好几米长的字条。这简直就是原始社会,生产效率低下的令人发指。发生个火灾什么的,直接Over。唯一的好处就是无需转换,可直接执行,但相对缺点来讲,这点好处完全可以被忽略。

2. 汇编语言

汇编语言是一种可编程器件的低级语言,亦称为符号语言。在汇编语言中,用助记符代替机器指令的操作码,用地址符号或标号代替指令或操作数的地址。在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令。也就是说不同平台之间不可直接移植,它是平台相关的,你在这个硬件平台写的汇编程序,换到另外一套硬件上去是运行不了的。 因此,汇编语言通常被应用在底层,硬件操作和高要求的程序优化的场合。驱动程序、嵌入式操作系统和实时运行程序较多使用汇编语言。相比于机器码,它更偏向人类的语言习惯,更易于编写和阅读,也就是有一点抽象符号概念化了,这大大提高了编程效率。但是,这依然是一种低级语言,还有改善和提高的空间。

上面一段看得晕没关系,简单地说就是汇编语言相比打孔纸条,对人类更友好一点了,至少能用几个类似ADD\CALL\MOV的英文缩写了。但是,它牺牲了一定的性能,并且依然不够友好。

3. C语言

在C语言之前其实还有很多低级语言,我们不关心它们。为了让编程更简单,更高效,聪明的计算机程序员,一步步发明了FORTRAN、BASIC、B等许多语言,然后在1972年诞生了无人不知,应用最广,影响最深,至今仍然地位不可动摇的C语言。

C语言为什么这么厉害?归根结底是一句话:直接操作硬件!同样的算法,用C语言,其执行效率超过JAVA等语言很多。那可能有人会问,C和汇编和机器码比呢?肯定是C慢,但是写个汇编程序和写个C程序的效率差别那就更大了。C语言在人类友好性和底层相关性上达到了一个高度的平衡。这两者是互相矛盾的,不可同时兼得。

C干了些什么?其实它就是在人类友好性方面相比以前跨出了更大一步。人类是方便了,可机器就迷糊了!你给我这么多字符都是啥意思?机器它只懂二进制啊!那么C的代码是如何被执行的呢?这就得请出编译器了!

编译器将编程语言写的代码翻译成机器能够执行或者说“看懂”的二进制机器码。

其实我们安装JAVA也好,C也好,Python也罢,主要就是安装的这个编程语言的“编译器”。

4. Python语言

在几十年前,C语言是当之无愧的高级语言代表,现在也依然是语言排行榜第二的霸主。然而,在很多领域,它已经不太适用了,现今更主流的语言是那些上手快、简单易懂,说白了就是门槛低的语言,让更多的人能进入程序员行业,让编程能更容易、更快是未来的发展趋势。也就是说,需要进一步让编程语言更贴近人类语言,更远离机器语言。

Python就是这么一种语言。它的语法简单明了,更贴近人类的使用习惯。作为一种动态解释性语言,让人们在写代码的时候可以更多的关注业务逻辑细节,而不需要花太多精力去关注数据类型定义、程序运行效率等!

既然都说的是机器不懂的“人话”,那必然也需要一个Python“编译器”。对于Python语言,广义上的“编译器”,叫做解释器。

三、 编译器与解释器

编译器/解释器:高级语言与机器之间的翻译官

都是将代码翻译成机器可以执行的二进制机器码,只不过在运行原理和翻译过程有不同而已。

那么两者有什么区别呢?

用一个通俗的例子进行比喻:我们去饭馆吃饭,点了八菜一汤。编译器的方式就是厨师把所有的菜给你全做好了,一起给你端上来,至于你在哪吃,怎么吃,随便。解释器的方式就是厨师做好一个菜给你上一个菜,你就吃这个菜,而且必须在饭店里吃。

至于更深入的编译器和解释器是如何工作的,请参考史诗巨著《编译原理》,这本书有个外号,叫做“龙书”。

四、 Python解释器种类

Python有好几种版本的解释器:

CPython:官方版本的解释器。这个解释器是用C语言开发的,所以叫CPython。CPython是使用最广的Python解释器。我们通常说的、下载的、讨论的、使用的都是这个解释器。

Ipython:基于CPython之上的一个交互式解释器,在交互方式上有所增强,执行Python代码的功能和CPython是完全一样的。CPython用>>>作为提示符,而IPython用In [序号]:作为提示符。

PyPy:一个追求执行速度的Python解释器。采用JIT技术,对Python代码进行动态编译(注意,不是解释),可以显著提高Python代码的执行速度。绝大部分CPython代码都可以在PyPy下运行,但还是有一些不同的,这就导致相同的Python代码在两种解释器下执行可能会有不同的结果。

Jython:运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。

IronPython:和Jython类似,只不过IronPython是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。

五、 Python的运行机制

Python作为动态解释性语言,其运行机制可参考下图(图片来自网络,其中的“编译器”是对解释器的广义称呼):

都说解释器慢,Python也有想办法提高一下运行速度的,那就是使用pyc文件。这点参考了JAVA的字节码做法,但并不完全类同。

我们编写的代码一般都会保存在以.py为后缀的文件中。在执行程序时,解释器逐行读取源代码并逐行解释运行。每执行一次,就重复一次这个过程,这其中耗费了大量的重复性的解释工作。为了减少这一重复性的解释工作,Python引入了pyc文件,pyc文件是将py文件的解释结果保存下来的文件,这样,下次再运行的时候就不用再解释了,直接使用pyc文件就可以了,这无疑大大提高了程序运行速度。

对于pyc文件,你必须知道以下几点:

  • 对于当前调用的主程序不会生成pyc文件
  • 以import xxx或from xxx import xxx等方式导入主程序的模块才会生成pyc文件
  • 每次使用pyc文件时,都会根据pyc文件的创建时间和源模块进行对比,如果源模块有修改,则重新创建pyc文件,并覆盖先前的pyc文件,如果没有修改,直接使用pyc文件代替模块;
  • pyc文件统一保存在模块所在目录的__pycache__文件夹内。

如下图所示,modula_a被module_main导入后会生成对应的pyc文件,但是module_main不会生成pyc文件!!

Python 编译器与解释器的更多相关文章

  1. 11 个最佳的 Python 编译器和解释器

    原作:Archie Mistry 翻译:豌豆花下猫@Python猫 原文:https://morioh.com/p/765b19f066a4 Python 是一门对初学者友好的编程语言,是一种多用途的 ...

  2. 详解python编译器和解释器的区别

    高级语言不能直接被机器所理解执行,所以都需要一个翻译的阶段,解释型语言用到的是解释器,编译型语言用到的是编译器. 编译型语言通常的执行过程是:源代码——预处理器——编译器——目标代码——链接器——可执 ...

  3. Python环境搭建-2 编译器和解释器

    编译器与解释器 编译器/解释器:高级语言与机器之间的翻译官 都是将代码翻译成机器可以执行的二进制机器码,只不过在运行原理和翻译过程有不同而已. 那么两者有什么区别呢? 编译器:先整体编译再执行 解释器 ...

  4. [译]Python编写虚拟解释器

    使用Python编写虚拟机解释器 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou,密码shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环 ...

  5. Numba:高性能Python编译器

    一.简介 Numba是一个开源JIT编译器,它将Python和NumPy代码的子集转换为快速机器代码. 二.主要特点 加速Python功能 Numba使用行业标准的LLVM编译器库在运行时将Pytho ...

  6. python设计模式之解释器模式

    python设计模式之解释器模式 对每个应用来说,至少有以下两种不同的用户分类. [ ] 基本用户:这类用户只希望能够凭直觉使用应用.他们不喜欢花太多时间配置或学习应用的内部.对他们来说,基本的用法就 ...

  7. python是一个解释器

    python是一个解释器 利用pip安装python插件的时候,观察到python的运作方式是逐步解释执行的 适合作为高级调度语言: 异常的处理以及效率应该是主要的问题

  8. Python自动化 【第九篇】:Python基础-线程、进程及python GIL全局解释器锁

    本节内容: 进程与线程区别 线程 a)  语法 b)  join c)  线程锁之Lock\Rlock\信号量 d)  将线程变为守护进程 e)  Event事件 f)   queue队列 g)  生 ...

  9. Linux 小知识翻译 - 「编译器和解释器」

    这次聊聊「编译器和解释器」. 编程语言中,有以C为代表的编译型语言和以Perl为代表的解释型语言.不管是哪种,程序都是以人类能够理解的形式记录的,这种形式计算机是无法理解的. 因此,才会有编译器和解释 ...

随机推荐

  1. Liunx学习总结(三)--用户和用户组管理

    用户和组的基本概念 用户和组是操作系统中一种身份认证资源. 每个用户都有用户名.用户的唯一编号 uid(user id).所属组及其默认的 shell,可能还有密码.家目录.附属组.注释信息等. 每个 ...

  2. unity之Layer作用

    1.使用layer做分层渲染 创建两个物体 添加AB两个层级 分别为两个物体设置对应的层级 为摄像机选择渲染层次(在这个例子中,取消对B层的渲染) 在游戏界面中,将不会显示B层的游戏对象

  3. eslint语法规范

    规则 缩进使用两个空格. eslint: indent   function hello (name) {   console.log('hi', name)   } 1 2 3 字符串使用单引号,除 ...

  4. hdu 1890 Robotic SortI(splay区间旋转操作)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 题解:splay又一高级的功能,区间旋转这个是用线段树这些实现不了的,这题可以学习splay的旋 ...

  5. Covered Points Count CF1000C 思维 前缀和 贪心

     Covered Points Count time limit per test 3 seconds memory limit per test 256 megabytes input standa ...

  6. codeforces 805 E. Ice cream coloring(dfs)

    题目链接:http://codeforces.com/contest/805/problem/E 题意:你有n个节点,这个n个节点构成一棵树.每个节点拥有有si个类型的ice,同一个节点的ice互相连 ...

  7. Hexo博客Next v7.X 主题升级,美化警示录

    本文转载于:Hexo博客Next v7.X 主题升级,美化警示录丨奥怪的小栈 前言 经历了好几天(懒癌晚期懒得数了)的与主题升级斗争后,我终于完成基本上完成了next主题的升级!升到了V7.3!哈哈哈 ...

  8. CH 4302 Interval GCD 题解

    题意 给定一个长度为N的数列A,以及M条指令 (N≤5* 10^5, M<=10^5),每条指令可能是以下两种之一: "C l r d",表示把 A[l],A[l+1],-, ...

  9. 洛谷 P4206 [NOI2005]聪聪与可可 题解

    题面 输入 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号. 接下来E行,每 ...

  10. @override 重写 与重载

    方法的重写(Overriding)和重载(Overloading)是Java多态性的不同表现.重写(Overriding)是父类与子类之间多态性的一种表现,而重载(Overloading)是一个类中多 ...