本文系《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 解释器。
一般的解释器执行程序的方法有三种:
- 直接执行程序;
- 将高级语言编写的程序转化为字节码( Bytecode ),并执行字节码;
- 用解释器包含的编译器对程序进行编译,并执行编译后的程序。
Python 语言的解释器采用的是第2种方法,如2.1.2节中所编写的 hello.py
文件,不论通过 IDE 还是在命令行中执行 python hello.py
,Python 解释器都会将源代码转化为字节码,生成扩展名为.pyc
的文件,此即为字节码文件,然后解释器执行字节码。
但是,如果按照图2-1-11的方式执行了该 Python 程序之后,并没有在当前目录中看到 .pyc
类型的字节码文件。这是因为用 python hello.py
的方式运行此程序,.pyc
文件运行之后并没有保存在硬盘中。需要换一种执行程序的方式。
qiwsir@qiwsirs-MBP codes % ls
hello.py
当前目录下只有一个 Python 文件 hello.py
,再执行:
qiwsir@qiwsirs-MBP codes % python -m py_compile hello.py
此指令的作用就是要生成 hello.py
对应的 .pyc
文件,并要保存到硬盘中。
qiwsir@qiwsirs-MBP codes % ls
__pycache__ hello.py
比前面的操作多了一个目录__pycache__
,进入到此目录中。
qiwsir@qiwsirs-MBP codes % cd __pycache__
qiwsir@qiwsirs-MBP __pycache__ % ls
hello.cpython-39.pyc
这里有一个 hello.cpython-39.pyc
文件,就是前面所说的由 Python 解释器生成的字节码文件。
qiwsir@qiwsirs-MBP __pycache__ % python hello.cpython-39.pyc
Hello World
再执行这个字节码文件,打印出了“ Hello World ”字样,与图2-1-11的运行效果相同。
下面做一个有意思的探索。如果将 hello.py
中增加一行,其完整代码是:
print("Hello World")
print("Life is short. You need Python.")
保存文件后,如果执行python hello.py
,会打印出什么?先猜,后操作,看结果:
qiwsir@qiwsirs-MacBook-Pro codes % python hello.py
Hello World
Life is short. You need Python.
果然不出所料。
再执行那个.pyc
文件,会是什么结果?
qiwsir@qiwsirs-MBP __pycache__ % python hello.cpython-39.pyc
Hello World
还是老样子。为什么?
虽然刚才修改了 hello.py
文件,在执行 python hello.py
的时候,肯定会生成新的 .pyc
文件,但是该文件并没有保存在硬盘中,现在所看到的 hello.cpython-39.pyc
还是未修改 hello.py
时生成的,故执行结果仍同以往。
再走一遍前面的流程,生成新的 .pyc
文件并保存,就会看到期望的结果了。
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
。
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
了吗?如果能觉察到,就不用阅读本书了——你就是超人。
★自学建议 “循环上升”是一种比较好的学习方法,即开始接触该知识的时候,从浅显的入手,随着能力和知识的积累,再对同样的内容深入学习。这种学习方法在中小学教育中体现得非常明显,比如初中物理中讲到“力”的概念,往往比较直观、简单;到高中物理再讲到“力”时,引入了初等数学的方法来解决部分问题;在大学物理中,对“力”的认知就更复杂了,比如
,用标量场
的负梯度表示保守力。 本书第1章1.3节以及本节所介绍的关于高级语言的“编译”、“解释”等知识,并非严谨且全面,读者在这里接触到的仅仅是一个最基本的认识。在此基础上,如果读者学有余力,可以借助其他学习资料或者网络,对与此有关的知识进行系统化整理,并形成专题的学习笔记或者综述。”