(2)Python如何运行程序

Python解释器简介:

Python不仅仅是一门编程语言,它也是一个名为解释器的软件包解释器是一种让其他程序运行起来的程序。当你编写了一段Python程序,Python解释器将读取程序,并按照其中的命令执行,得出结果。实际上,解释器是代码与机器的计算机硬件之间的软件逻辑层


程序执行:

编写或运行Python脚本的意义,取决于你从什么角度都看待这个问题。

  • 程序员的视角:就最简单的形式而言,一个Python程序仅是一个包含Python语句的文本文件。例如,下面这个文件,就算我们能够想到的最简单的Python脚本,但它算得上是一个典型的Python程序:

     print('hello world')
    print(2 ** 100)
  • Python的视角:当Python运行脚本时,在代码开始进行处理之前,Python还会执行一些步骤。确切地说,第一步是编译成所谓的”字节码“,之后将其转发到所谓的”虚拟机“中。

    1. 字节码编译:当程序执行时,Python内部(对大多数用户是完全隐藏的)会先将源代码(文件中的语句)编译成所谓的字节码的形式。编译是一个简单的翻译步骤,而且字节码是源代码底层的,与平台无关的表现形式。概况地说,Python通过把每一条源语句分解为单一步骤来将这些源语句翻译成一组字节码指令。这些字节码可以提高执行速度:比起文本文件中原始的源代码语句,字节码的运行速度要快得多。

      你会注意到,前面一段所提到的这个过程对于你来说是完全隐藏起来的。但Python进程在机器上拥有写入权限,那么它将把程序的字节码保存在一个以.pyc为扩展名的文件。当程序运行之后,你会在那些源代码的附近(即同一目录下)看到这些文件。

      Python这样保存字节码是作为一种启动速度的优化。下一次运行程序时,如果你在上次保存字节码之后没有修改过源代码的话,Python将会加载.pyc并跳过编译这个步骤。当Python必须重编译时,它会自动检查源文件和字节码文件的时间戳:如果你又保存了源代码,下次程序运行时,字节码将自动重新创建。

      如果Python无法在机器上写入字节码,程序仍然可以工作:字节码将会在内存中生成并在程序结束时简单地丢弃。尽管这样,由于.pyc能够加速启动,你最好保证在大型程序中可以写入。字节码文件同样是分发Python程序的方法之一:如果Python找到的都是.pyc文件,它也很乐意运行这个程序,尽管这里没有原始的.pyc源代码文件。

    2. Python虚拟机(PVM)

      一旦程序编译成字节码(或字节码从已经存在的.pyc文件中载入),之后的字节码发到通常称为PVM上来执行。PVM听起来比它本身给人的印象更深刻一些。实际上,它不是一个独立的程序,不需要安装。事实上,PVM就算迭代运行字节码指令的一个大循环,一个接一个完成操作。PVM是Python的运行引擎,它时常表现为Python系统的一部分,并且它是实际运行脚本的组件。从技术上讲,它才是所谓”Python解析器“的最后一步。

      运行时的结构如下所示,请记住所有的这些复杂性都是有意地对Python程序员隐藏起来的。字节码的编译是自动完成的,而且PVM也仅仅是安装在机器上的Python系统的一部分。再一次说明,程序员只需简单地编写代码并运行包含有语句的文件。


性能的含义:

与C和C++这类完全编译语言不同,Python的工作中通常没有“build”或“make”的步骤:代码在写好之后立即运行。另外一个就是,Python字节码不是机器的二进制代码(例如,Intel芯片的指令)。字节码是特定于Python的一种变现形式。另一方面,和其他经典的解释器不同,这里仍有内部的编译步骤:Python并不需要反复地重分析和重分解每一行语句。实际的效果就是纯Python代码的运行速度介于传统的编译语言和传统的解释语言之间


开发的含义:

Python执行模块的另一个情况是其开发和执行的环境实际上并没有区别。也就是说,编译和执行源代码的系统是同一个系统。Python中,编译器总是在在运行时出现,并且是运行程序系统的一部分。

这使开发周期大大缩短。在程序开始执行之前不需要预编译和连接;只需要简单地输入并运行代码即可。这同样使Python具有更多的动态语言特性:在运行时,Python程序去构建并执行另一个Python程序是有可能的,而且往往是非常方便的。例如,evalexec内置模块,能够接受并运行包含Python程序代码的字符串。这种结构是Python能够实现产品定制的原因:因为Python代码可以动态地修改,用户可以改进系统内部的Python部分,而不需要拥有或编译整个系统的代码。

从更基础的角度来说,牢记我们在Python中真正拥有的只有运行时:完全不需要初始的编译阶段,所有的事情都是在程序运行时发生的。这甚至还包括了建立函数和类的操作以及连接的模块。这些事情对于静态语言往往是发生在执行之前的,而在Python中是与程序的执行同时进行的。就像我们看到的那样,实际的效果就是Python比一些读者所用的程序语言带来了更加动态的编程体验。


Python实现的替代者:

简单来说有三种主要的实现方式:

  1. CPython

  2. Jython

  3. IronPython


执行优化工具:

它们试着优化基本执行模块,这些系统不是现阶段学习Python的必备知识,但简要了解这些执行模块可以帮助你更轻松地掌握这些模块。

  1. Psyco实时编译器

    Psyco系统是一个扩展字节码执行模块的组件,可以让程序运行得更快。Psyco是一个PVM的增强工具,这个工具收集并使用信息,在程序运行时,可以将部分程序的字节码转换成底层的真正的二进制机器代码,从而实现更快的执行速度。在开发的过程中,Psyco无需代码的修改或独立的编译步骤即可完成这一转换

    概况地讲,当程序运行时,Psyco收集了正在传递过程中的对象的类别信息,这些信息可以用来裁剪对象的类型,从而生成高效的机器代码。机器代码一旦生成后,就替代了对应的原始字节码,从而加快程序的整体执行速度。实际的效果就是,通过使用Psyco,使程序在整个运行过程中执行得更快。在理想的情况下,一些通过Psyco优化的Python代码的执行速度可以像编译好的C代码一样快。

    因为字节码的转换与程序运行同时发生,所以Psyco往往被看作是一个即时编译器(JIT)。Psyco是一个专用的JIT编译器:它生成机器代码将数据类型精简至你程序实际上所使用的类型。例如,如果程序的一部分在不同的时候采用了不用的数据类型,Psyco可以生成不同版本的机器码用来支持每一个不同的类型组合。

    Psyco最大的缺点就是它实际上只能够为Intel x86构架的芯片生成机器代码

  2. Shedskin C++ 转换器

    Shedskin是一个引擎系统,它采用了一种不同的Python程序执行方法:它尝试将Python代码变为C++代码,然后使用机器中的C++编译器将得到的C++代码编译为机器代码。正是如此,它以一种平台无关的方式来运行Python代码。

  3. 冻结二进制文件

    有时候人们需要一个“真正的”Python编译器,实际上他们真正需要的是得到一种能够让Python程序生成独立的可执行二进制代码的简单方法。这是一个比执行流程概念更接近打包分发概念的东西,但是二者之间或多或少有些联系。通过从网络上获得的一些第三方工具,将Python程序转为可执行程序(在Python世界中称作冻结二进制文件,Frozen Binary)是有可能的。

    冻结二进制文件能够将程序的字节码、PVM(解释器)以及任何程序所需要的Python支持文件捆绑在一起形成一个单独的文件包。过程会有一些不同,但是实际的结果将会是一个单独的可执行二进制程序(例如,Windows系统中的.exe文件),这个程序可以很容易地向客户分发。这就好像将字节码和PVM混合在一起形成一个独立的组件------冻结二进制文件。

    如今,主要有三种系统能够生成冻结二进制文件:py2exe(Window下使用)、PyInstaller(和py2exe类似,它能够在Linux及UNIX上使用,并且能够生成自安装的二进制文件)以及freeze(最初始的版本)。你可以单独获得这些工具,它们也是免费的。

    冻结二进制文件与真实的编译输出结果有所不同:它们通过虚拟机运行字节码。因此,如果离开了必要的初始改进,冻结二进制文件和最初的源代码程序运行速度完全相同。冻结二进制文件并不小(因为包括PVM),但是以目前的标准来衡量,它们的文件也不是特别的大。因为在冻结二进制文件中嵌入了Python,接受端并不需要安装Python来运行这些冻结二进制文件。此外,由于代码嵌入在冻结二进制代码之中,对于接收者来说,代码都是隐藏起来的。

    对商业软件的开发者来说,单文件封装的构架特别有吸引力。例如,一个Python编码的基于tkinter工具包的用户界面可以封装成一个可执行文件,并且可以作为一个CD中或网络上的独立程序进行发售。终端用户无需安装(甚至没有必要知道)Python去运行这些发售的程序。终端用户无需安装(甚至没有必要知道)Python去运行这些发售的程序。


本章习题:

  1. 什么是Python解释器?

    Python解释器是运行Python程序的程序

  2. 什么是源代码?

    源代码是为程序编写的语句:它包括了文本文件(通常以.py为后缀名)的文本

  3. 什么是字节码?

    字节码是Python将程序编译后所得到的底层形式,Python自动将字节码保存到后缀名为.pyc的文件中

  4. 什么是PVM?

    PVM是Python虚拟机

  5. 请列出两个Python标准执行模块的变体的名字

    PsycoShedskin以及forzen binarie是执行模块的所有变体

  6. CPythonJython以及IronPython有什么不同?

    CPython是Python语言的标准实现。JythonIronPython分别是Python程序的Java和.NET的实现;它们都是Python的编译器的替代实现。

Python学习日志-02的更多相关文章

  1. Python学习日志9月13日

    昨天的学习日志没有写,乱忙了一整天,政治电脑. 好奇心重,想要给电脑装上传说中LInux操作系统,各种小问题折腾到半夜,今天又折腾到晚上才真正的装上系统. 可是装上系统后又发现各种的不好用.虽然界面比 ...

  2. python学习笔记-02

    四.函数 1.定义函数 (1)定义规则 介绍列表方法的时候已经大概说过函数,学过数学的人都知道函数,给一个参数返回一个值.函数也可以自己定义.用如下的格式: >>>def 函数名(参 ...

  3. Python 学习日志9月19日

    9月19日 周二 今天是普通的一天,昨天也是普通的一天,刚才我差点忘记写日志,突然想起来有个事情没做,回来写. 今天早晨学习<Head First HTML and CSS>第十一章节“布 ...

  4. Python学习日志_2017/09/08

    今天早晨学习了<Head First :HTML and CSS>:学习了两个章节,感觉从基础学习特别的踏实,能看懂的同时踏踏实实的锻炼了基础的能力.我个人认为无论哪个行业,最重要的永远是 ...

  5. Python学习【02】Python基础

    一.Python内部执行过程 1.Python的后缀名可以是任意? print("hello,world")  保存成  .py / .txt / .sb / .aaa 都可以用在 ...

  6. Python 学习日志9月20日

    9月20日 周三 多大年龄了,还活得像个小孩.——急什么,人生又不长. 你习惯了思考宇宙星辰,一百年真的不长,一生也就不那么长,许多人的价值观念你也就无法理解.同样,许多人也无法理解你的价值观念,感兴 ...

  7. Python 学习日志9月18日

    今天早晨学习了<Head First HTML and CSS>,第10章“div and span”. 看完并且做了练习也算是对div和span扫了个盲,需要在实践练习中加强理解与掌握. ...

  8. Python学习日志9月17日 一周总结

    周一,9月11日 这天写的是过去一周的周总结,我从中找出当天的内容. 这天早晨给电脑折腾装机,早晨基本上没有学习,休息了一个早晨. 下午写的上周总结,完事做mooc爬虫课的作业,<Think P ...

  9. Python学习日志9月16日

    刚才我差点睡着了,差资料的时候太费神,有些累. 今天早晨学习了<head first HTML and CSS>,今天把昨天没看了的关于字体和颜色的一章节看完了,真长.我详细的做了笔记,并 ...

随机推荐

  1. rancher证书过期

    背景 无法打开rancher服务,报错如下截图,可以看出是证书过期了无法连上k8s,注意这里的证书是rancher自身证书并非k8s证书. 解决方法 rancher升级:https://rancher ...

  2. [Android应用开发] 05.广播和服务

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  3. 接口(interface)的使用

    类实现接口就具有接口的功能 实现可以多实现,实现多个接口 package cm.aff.abst; /* 接口(interface)是与类并行的一个概念 1. 接口可以看做是一个特殊的抽象类,是常量与 ...

  4. 2020本科校招-从小白到拿到30k offer的学习经历

    本文是个人的2020年年中总结 还有十几天就要毕业,面临着身份从学生到互联网社畜的转变,未来的一切捉摸不定,但凡心中万千情绪,也只能「但行好事,莫问前程」. 介绍下博主背景:计算机本科大四,刚进大三时 ...

  5. Chisel3 - Tutorial - ShiftRegister

    https://mp.weixin.qq.com/s/LKiXUgSnt3DzgFLa9zLCmQ   简单的寄存器在时钟的驱动下,逐个往下传值.   参考链接: https://github.com ...

  6. 【Linux】将javaweb项目部署到CentOS的tomcat上

    1.将项目打包成war包 build之后war文件就生成了. 2.拷贝war文件到CentOS的tomcat的项目文件夹中 用WinSCP将文件粘帖进这个文件夹中 /wocloud/tomcat_cl ...

  7. java方法句柄-----2.方法句柄的获取、变换、特殊方法句柄

    目录 1.获取方法句柄 1.1查找构造方法.一般方法和静态方法的方法句柄 1.2 查找类中的特殊方法(类中的私有方法) 1.3 查找类中静态域和一般域 1.4 通过反射API得到的Constructo ...

  8. Java实现 LeetCode 798 得分最高的最小轮调 (暴力分析)

    798. 得分最高的最小轮调 给定一个数组 A,我们可以将它按一个非负整数 K 进行轮调,这样可以使数组变为 A[K], A[K+1], A{K+2], - A[A.length - 1], A[0] ...

  9. Java实现 LeetCode 347 前 K 个高频元素

    347. 前 K 个高频元素 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输 ...

  10. JavaScript实现html购物车代码

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...