python运行机制以及import函数执行过程

1 解释器和编译器

我们经常使用的各种语言大部分都是高级语言,高级语言计算机是无法读懂的,需要首先编译为机器可以读懂的汇编语言,然后让机器“翻译”为由0和1组成的二进制文件机器才可以执行。最直接的一个想法是我们直接将代码通过一个“黑盒子”变为二进制代码并运行,编译翻译这些工作都由这个“黑盒子”来完成,这个黑盒子其实就是我们说的解释器,我们在任意系统上,只要有这个高级语言对应的解释器,我们就可以直接运行该程序,所以解释器对应的程序是可以跨平台的。解释器对应的语言一般为解释性语言,例如Python。在这里插入图片描述

但是使用解释器运行的程序是我们临时运行的,一旦我们把这个程序关闭,那我们下次需要运行该程序的时候又要重新打开解释器执行,这非常消耗资源,那么就不能有一种方法可以把我们生成的程序“固定”下来吗,每次运行无需让他重新进行编译再执行,而是使用已经编译好的代码再执行,但由于我们不同的机器使用的硬件逻辑是不一致的,这导致我们在A机器上编译的程序,到了B机器上就读不懂了。所以为了我们编译的程序可以在不同平台上读懂,我们的编译器会首先将其生成一个目标文件作为中间文件,这个中间文件是任意平台都是可以被读取的。然后链接器会将目标文件进行链接变成二进制文件即可进行执行。这样效率就得到了大大的提高,程序每次只需要链接而无需编译过程,就可以运行。常见的语言有C++和C。但这样的代码跨平台特性较差,因为如果平台没有特定的链接器,程序就无法运行了。
在这里插入图片描述

2 程序解释过程

python作为一门动态语言,使用动态编译技术。上述我们提到了python的运行是通过解释器来完成的,解释器会逐步将每条语法进行解释并执行,无需中间手动对起进行编译。使用python写完的代码,在解释器中的运行过程如下:

  1. 源代码:在 Python 中,我们使用文本文件作为源代码。源代码是由程序员编写的可读性较高的 Python 代码。
  2. 词法分析:在这一步骤中,解释器/编译器将源代码分解成一系列的词法单元(token),其中每个词法单元代表着一个语法单元。例如,如果我们有一个变量声明”num = 10″,那么词法分析器将生成三个词法单元:标识符”num”、操作符”=”和数字”10″。
  3. 语法分析:在这一步骤中,解释器/编译器将词法单元转换为抽象语法树(Abstract Syntax Tree,AST)。AST 是一种将源代码表示为树形结构的数据结构,每个节点代表着一个语法结构。
  4. 语义分析:在这一步骤中,解释器/编译器检查源代码是否符合语法规则,并进行类型检查等语义检查。如果源代码中存在语法错误或类型错误,解释器/编译器将生成相应的错误提示。
  5. 中间代码生成:在这一步骤中,解释器/编译器将抽象语法树转换为中间代码。中间代码是一种与具体硬件无关的代码,通常是一种类似于汇编语言的低级语言。
  6. 优化:在这一步骤中,编译器对中间代码进行优化,目的是提高代码执行的效率。优化是一个复杂的过程,包括常量折叠、循环优化、内联函数等。
  7. 机器代码生成:如果是编译模式,这一步骤将中间代码转换为机器代码。机器代码是一种由计算机直接执行的二进制代码。
  8. 执行:最后,机器代码被计算机执行,程序的功能得以实现。
# 源代码
num = 10
result = 0

# 词法分析
tokens = ['num', '=', '10', 'result', '=', '0']

# 语法分析
AST = 'Assign(Variable(num), Integer(10)); Assign(Variable(result), Integer(0))'

# 语义分析
# 检查变量类型、语法错误等

# 中间代码生成
IR = 'ASSIGN num 10; ASSIGN result 0'

# 优化
# 常量折叠、循环优化等

# 机器代码生成
machine_code = 'MOV R1, 10; MOV R2, 0'

# 执行
# 将机器代码加载到 CPU,并执行相应的操作

针对代码中我们常见的 import,我们可以知道他在词法分析这一步被解析。Python通过 import 语句来实现类库的引用,当我们执行一行 from package import module as mymodule 命令时,Python解释器会查找package 这个包的module模块,并将该模块作为 mymodule 引入到当前的工作空间。所以import语句主要是做了二件事:

  1. 查找相应的module
  2. 加载module到local namespace

在import的第一个阶段,主要是完成了查找要引入模块的功能。查找时首先检查 sys.modules (保存了之前import的类库的缓存),如果module没有被找到,则按照下面的搜索路径查找模块:

  1. py 所在文件的目录
  2. PYTHONPATH 中的目录
  3. python安装目录,UNIX下,默认路径一般为/usr/local/lib/python/
  4. 3.x 中.pth 文件内容

参考:Python笔记03:python中用import导入包的机制原理是什么?

在我们使用 from package import module 的时候,可以是具体的module也可以是全部module。例如 from numpy import power 和 from numpy import *,如果使用 * 会导致导入所有的module并在后续执行一遍,虽然可能没有任何输出上的不同,但是程序的运行时间会有所增加。例如我们做了一个实验:

在这里插入图片描述
在这里插入图片描述
如果将numpy函数全部导入则会时间增加

在这里插入图片描述
在这里插入图片描述

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值