《Python完全自学教程》免费在线连载2.1.3

2022-04-01 09:55:01 浏览数 (1)

本文系《Python完全自学教程》第2章2.1.3节,更多内容,请访问 http://www.itdiffer.com/self-learning.html

2.1.3 解释器

经过第1章的1.2节和1.3节的自学,已经知道计算机能“认识”的是机器语言,2.1.2节所编写的 hello.py 程序,是用高级语言编写而成,计算机不能直接“认识”,为此要经过“翻译”过程。对于 Python 程序而言,用于“翻译”的叫做 Python 解释器( Interpreter )。目前常见的 Python 解释器包括:CPython、JPython、IPython、PyPy、IronPython 五个版本。当读者已经在本地计算机安装好 Python 之后(参阅第1章1.7节),就已经将其中最常用的一个解释器 CPython 安装好了。CPython 是使用 C语言开发的 Python 解释器,也是标准的 Python 解释器,是使用最广泛的 Python 解释器。

一般的解释器执行程序的方法有三种:

  1. 直接执行程序;
  2. 将高级语言编写的程序转化为字节码( Bytecode ),并执行字节码;
  3. 用解释器包含的编译器对程序进行编译,并执行编译后的程序。

Python 语言的解释器采用的是第2种方法,如2.1.2节中所编写的 hello.py 文件,不论通过 IDE 还是在命令行中执行 python hello.py ,Python 解释器都会将源代码转化为字节码,生成扩展名为.pyc的文件,此即为字节码文件,然后解释器执行字节码。

但是,如果按照图2-1-11的方式执行了该 Python 程序之后,并没有在当前目录中看到 .pyc 类型的字节码文件。这是因为用 python hello.py 的方式运行此程序,.pyc 文件运行之后并没有保存在硬盘中。需要换一种执行程序的方式。

代码语言:javascript复制
qiwsir@qiwsirs-MBP codes % ls
hello.py

当前目录下只有一个 Python 文件 hello.py ,再执行:

代码语言:javascript复制
qiwsir@qiwsirs-MBP codes % python -m py_compile hello.py

此指令的作用就是要生成 hello.py 对应的 .pyc 文件,并要保存到硬盘中。

代码语言:javascript复制
qiwsir@qiwsirs-MBP codes % ls
__pycache__ hello.py

比前面的操作多了一个目录__pycache__,进入到此目录中。

代码语言:javascript复制
qiwsir@qiwsirs-MBP codes % cd __pycache__
qiwsir@qiwsirs-MBP __pycache__ % ls
hello.cpython-39.pyc

这里有一个 hello.cpython-39.pyc 文件,就是前面所说的由 Python 解释器生成的字节码文件。

代码语言:javascript复制
qiwsir@qiwsirs-MBP __pycache__ % python hello.cpython-39.pyc
Hello World

再执行这个字节码文件,打印出了“ Hello World ”字样,与图2-1-11的运行效果相同。

下面做一个有意思的探索。如果将 hello.py 中增加一行,其完整代码是:

代码语言:javascript复制
print("Hello World")
print("Life is short. You need Python.")

保存文件后,如果执行python hello.py,会打印出什么?先猜,后操作,看结果:

代码语言:javascript复制
qiwsir@qiwsirs-MacBook-Pro codes % python hello.py
Hello World
Life is short. You need Python.

果然不出所料。

再执行那个.pyc文件,会是什么结果?

代码语言:javascript复制
qiwsir@qiwsirs-MBP __pycache__ % python hello.cpython-39.pyc
Hello World

还是老样子。为什么?

虽然刚才修改了 hello.py 文件,在执行 python hello.py 的时候,肯定会生成新的 .pyc 文件,但是该文件并没有保存在硬盘中,现在所看到的 hello.cpython-39.pyc 还是未修改 hello.py 时生成的,故执行结果仍同以往。

再走一遍前面的流程,生成新的 .pyc 文件并保存,就会看到期望的结果了。

代码语言:javascript复制
qiwsir@qiwsirs-MBP codes % python -m py_compile hello.py
qiwsir@qiwsirs-MBP codes % cd __pycache__
qiwsir@qiwsirs-MBP __pycache__ % ls
hello.cpython-39.pyc
qiwsir@qiwsirs-MBP __pycache__ % python hello.cpython-39.pyc
Hello World
Life is short. You need Python.

Python 解释器执行字节码文件的速度要快于执行源代码文件,因此有的时候会发布 .pyc 文件——当然,如果源代码修改了,还需要重新发布。例如将 hello.cpython-39.pyc 文件移动到上一级目录,并更名为fasthello.pyc

代码语言:javascript复制
qiwsir@qiwsirs-MBP __pycache__ % mv ./hello.cpython-39.pyc ../fasthello.pyc
qiwsir@qiwsirs-MBP __pycache__ % cd ..
qiwsir@qiwsirs-MBP codes % ls
__pycache__ fasthello.pyc hello.py

然后执行它:

代码语言:javascript复制
qiwsir@qiwsirs-MBP codes % python fasthello.pyc
Hello World
Life is short. You need Python.

觉察到 python fasthello.pyc 的运行速度快于执行 python hello.py 了吗?如果能觉察到,就不用阅读本书了——你就是超人。

自学建议 “循环上升”是一种比较好的学习方法,即开始接触该知识的时候,从浅显的入手,随着能力和知识的积累,再对同样的内容深入学习。这种学习方法在中小学教育中体现得非常明显,比如初中物理中讲到“力”的概念,往往比较直观、简单;到高中物理再讲到“力”时,引入了初等数学的方法来解决部分问题;在大学物理中,对“力”的认知就更复杂了,比如

pmb{F}=-pmb{U} = -left(frac{partial U}{partial x}pmb{e}_x frac{partial U}{partial y}pmb{e}_y frac{partial U}{partial z}pmb{e}_zright)

,用标量场

U

的负梯度表示保守力。 本书第1章1.3节以及本节所介绍的关于高级语言的“编译”、“解释”等知识,并非严谨且全面,读者在这里接触到的仅仅是一个最基本的认识。在此基础上,如果读者学有余力,可以借助其他学习资料或者网络,对与此有关的知识进行系统化整理,并形成专题的学习笔记或者综述。”

0 人点赞