Python编译过程和执行原理

Alt

hello,这里是Token_w的文章,主要讲解python的基础学习,希望对大家有所帮助
整理不易,感觉还不错的可以点赞收藏评论支持,感谢!

目录

  • 一. Python执行原理
  • 二. Python内部执行过程
    • 2.1 编译过程概述
    • 2.2 过程图解
    • 2.4 codeobject对象的属性

一. Python执行原理

这里的解释执行是相对于编译执行而言的。我们都知道,使用C/C++之类的编译性语言编写的程序,是需要从源文件转换成计算机使用的机器语言,经过链接器链接之后形成了二进制的可执行文件。运行该程序的时候,就可以把二进制程序从硬盘载入到内存中并运行。

但是对于Python而言,Python源码不需要编译成二进制代码,它可以直接从源代码运行程序。当我们运行Python文件程序的时候,Python解释器将源代码转换为字节码,然后再由Python解释器来执行这些字节码。这样,Python就不用担心程序的编译,库的链接加载等问题了。

对于Python解释语言,有以下3方面的特性:

  1. 每次运行都要进行转换成字节码,然后再有虚拟机把字节码转换成机器语言,最后才能在硬件上运行。与编译性语言相比,每次多出了编译和链接的过程,性能肯定会受到影响。
  2. 由于不用关心程序的编译和库的链接等问题,开发的工作也就更加轻松啦。
  3. Python代码与机器底层更远了,Python程序更加易于移植,基本上无需改动就能在多平台上运行。

在具体计算机上实现一种语言,首先要确定的是表示该语言语义解释的虚拟计算机,一个关键的问题是程序执行时的基本表示是实际计算机上的机器语言还是虚拟机的机器语言。这个问题决定了语言的实现。根据这个问题的回答,可以将程序设计语言划分为两大类:编译型语言和解释型语言。

  1. 编译实现的语言,如:C、C++、Fortran、Pascal、Ada。由编译型语言编写的源程序需要经过编译,汇编和链接才能输出目标代码,然后由机器执行目标代码。目标代码是有机器指令组成,不能独立运行,因为源程序中可能使用了一些汇编程序不能解释引用的库函数,而库函数又不在源程序中,此时还需要链接程序完成外部引用和目标模板调用的链接任务,最后才能输出可执行代码。
  2. 解释型语言,解释器不产生目标机器代码,而是产生中间代码,这种中间代码与机器代码不同,中间代码的解释是由软件支持的,不能直接使用在硬件上。该软件解释器通常会导致执行效率较低,用解释型语言编写的程序是由另一个可以理解中间代码的解释程序执行的。和编译的程序不同的是,解释程序的任务是逐一将源代码的语句解释成可执行的机器指令,不需要将源程序翻译成目标代码再执行。对于解释型语言,需要一个专门的解释器来执行该程序,每条语句只有在执行是才能被翻译,这种解释型语言每执行一次就翻译一次,因而效率低下。
  3. Java解释器,java很特殊,java是需要编译的,但是没有直接编译成机器语言,而是编译成字节码,然后在Java虚拟机上用解释的方式执行字节码。Python也使用了类似的方式,先将Python编译成Python字节码,然后由一个专门的Python字节码解释器负责解释执行字节码。
  4. Python是一门解释语言,但是出于效率的考虑,提供了一种编译的方法。编译之后就得到pyc文件,存储了字节码。Python这点和java很类似,但是java与Python不同的是,Python是一个解释型的语言,所以编译字节码不是一个强制的操作,事实上,编译是一个自动的过程,一般不会在意它的存在。编译成字节码可以节省加载模块的时间,提高效率。
  5. 除了效率之外,字节码的形式也增加了反向工程的难度,可以保护源代码。这个只是一定程度上的保护,反编译还是可以的。

二. Python内部执行过程

2.1 编译过程概述

当我们执行Python代码的时候,在Python解释器用四个过程“拆解”我们的代码,最终被CPU执行返回给用户。

首先当用户键入代码交给Python处理的时候会先进行词法分析,例如用户键入关键字或者当输入关键字有误时,都会被词法分析所触发,不正确的代码将不会被执行。

下一步Python会进行语法分析,例如当"for i in test:"中,test后面的冒号如果被写为其他符号,代码依旧不会被执行。

下面进入最关键的过程,在执行Python前,Python会生成.pyc文件,这个文件就是字节码,如果我们不小心修改了字节码,Python下次重新编译该程序时会和其上次生成的字节码文件进行比较,如果不匹配则会将被修改过的字节码文件进行覆盖,以确保每次编译后字节码的准确性。

那么什么是字节码?字节码在Python虚拟机程序里对应的是PyCodeObject对象。.pyc文件是字节码在磁盘上的表现形式。简单来说就是在编译代码的过程中,首先会将代码中的函数、类等对象分类处理,然后生成字节码文件。有了字节码文件,CPU可以直接识别字节码文件进行处理,接着Python就可执行了。

2.2 过程图解

在这里插入图片描述
2.3 编译字节码
Python中有一个内置函数compile(),可以将源文件编译成codeobject,首先看这个函数的说明:

compile(...) compile(source, filename, mode[, flags[, dont_inherit]]) -> code object

参数1:源文件的内容字符串

参数2:源文件名称

参数3:exec-编译module,single-编译一个声明,eval-编译一个表达式 一般使用前三个参数就够了

使用示例:

#src_file.py
#some function
def f(d=0):c=1print "hello"
a=9
b=8
f()
>>> a=open('src_file.py','r').read()    #命令行模式中打开源文件进行编译
>>> co=compile(a,'src_file','exec')
>>> type(co)
<type 'code'>    #编译出了codeobject对象

2.4 codeobject对象的属性

codeobject有哪些变量,接上节的内容分析一下:

print(co.co_names)   #所有的符号名称
# ('f', 'a', 'b')
print(co.co_name)#模块名、函数名、类名
# <module>
print(co.co_consts)  #常量集合、函数f和两个int常量a,b,d
# (0, <code object f at 0xb7273b18, file "src_file", line 2>, 9, 8, None)
print(co.co_consts[1].co_varnames)  #可以看到f函数也是一个codeobject,打印f中的局部变量
# ('c',)
print(co.co_code)  #字节码指令
# dZdZdZedS
print(co.co_consts[1].co_firstlineno)  #代码块在文件中的起始行号
# 2
print(co.co_stacksize)  #代码栈大小
# 2
print(co.co_filename)  #文件名
# src_file    #模块名、函数名、类名 

codeobject的co_code代表了字节码,这个字节码有什么含义?我们可以使用dis模块进行Python的反编译:

import dis
dis.dis(co)
print(output)
'''2        0 LOAD_CONST               0 (0)3 LOAD_CONST               1 (<code object f at 0xb7273b18, file "src_file", line 2>)6 MAKE_FUNCTION            19 STORE_NAME               0 (f)5        12 LOAD_CONST              2 (9)15 STORE_NAME              1 (a)6        18 LOAD_CONST              3 (8)21 STORE_NAME              2 (b)7        24 LOAD_NAME               0 (f)27 CALL_FUNCTION           030 POP_TOP             31 LOAD_CONST              4 (None)34 RETURN_VALUE '''

从反编译的结果来看,Python字节码其实是模仿的x86的汇编,将代码编译成一条一条的指令交给一个虚拟的cpu去执行。

  • 第一列:行号
  • 第二列:指令在代码块中的偏移量
  • 第三列:指令
  • 第四列:操作数
  • 第五列:操作数说明

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/8121.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

遥感数字图像处理实验教程(韦玉春)--部分实验问题回答

个人的学习思考&#xff0c;仅供参考。 目录 实验三、图像合成和显示增强 一、目的 二、要求 三、实验 实验五、图像变换 一、目的 二、要求 三、实验 实验六、图像滤波 一、目的 二、要求 三、实验 实验七、图像分割 一、目的 二、要求 三、实验 实验八、图…

linux判断端口是否占用(好用)

netstat 一般的话使用 netstat -tunlp | grep xxx参数作用-t指明显示TCP端口-u指明显示UDP端口-l仅显示监听套接字(所谓套接字就是使应用程序能够读写与收发通讯协议(protocol)与资料的程序)-p显示进程标识符和程序名称&#xff0c;每一个套接字/端口都属于一个程序。-n不进行…

爬虫002_python程序的终端运行_文件运行_ipython的使用---python工作笔记020

用python运行一个文件,就是要写一个.py结尾的文件 然后保存 然后直接cmd中,python 然后写上py文件的路径就可以了 然后看一下内容 看一下终端中运行,直接输入python进入python环境,然后写python代码 回车运行 退出可以用exit()

设计模式——单例模式

1 概述 单例模式就是保证一个类只有一个对象实例。 为了保证无法创建多余的对象实例&#xff0c;单例类中需要自己创建对象实例&#xff0c;并把自己的构造方法私有化以防止其他地方调用创建对象&#xff0c;且需要提供一个公共的方法给其他类来获取该单例类的实例。 同时单例…

Linux笔记——rpm与yum下载软件命令介绍

系列文章目录 Linux笔记——进程管理Linux笔记——进程管理与网络监控技术讲解Linux笔记——进程管理 Linux笔记——管道相关命令以及shell编程 Linux笔记——磁盘进行分区与挂载介绍 文章目录 系列文章目录 前言 一 RPM介绍 1.1 RPM简单介绍 1.2 RPM命令语法 1.2.1 …

数学建模学习(2):数学建模各类常用的算法全解析

一、评价类算法 常见的评价算法 1.层次分析法 基本思想 是定性与定量相结合的多准则决策、评价方法。将决策的有关元素分解成 目标层、准则层和方案层 &#xff0c;并通过人们的 判断对决策方案的 优劣进行排序 &#xff0c;在此基础上进行定性和定量分析。它把人的思维过程…

Python怎么实现模式匹配

什么是模式匹配 模式匹配是一种用于在数据中寻找特定模式或结构的技术。它可以用于识别、查找和提取符合特定模式要求的数据。 在计算机科学中&#xff0c;模式匹配通常用于字符串处理和数据分析领域。一些常见的模式匹配模式包括&#xff1a; 1. 字符串匹配&#xff1a;在一…

23 自定义控件

案例&#xff1a;组合Spin Box和Horizontal Slider实现联动 新建Qt设计师界面&#xff1a; 选择Widget&#xff1a; 选择类名&#xff08;生成.h、.cpp、.ui文件&#xff09; 在smallWidget.ui中使用Spin Box和Horizontal Slider控件 可以自定义数字区间&#xff1a; 在主窗口w…

Docker 单机/集群 部署 Nacos2.2.0

单机部署 1- 拉取镜像 docker pull nacos/nacos-server:v2.2.02- 准备挂载的配置文件目录和日志目录 日志目录(空目录)&#xff1a;./nacos/logs配置文件&#xff1a;./nacos/conf/application.properties 从官网下载 nacos 压缩包&#xff1a;Release 2.2.0 (Dec 14, 2022…

18.背景轮播

背景轮播 html部分 <div class"container"><div class"slide active" style"background-image: url(./static/20180529205331_yhGyf.jpeg);"></div><div class"slide " style"background-image: url(./s…

【数据挖掘】使用 LSTM 进行时间和序列预测

一、说明 每天&#xff0c;人类在执行诸如过马路之类的任务时都会做出被动预测&#xff0c;他们估计汽车的速度和与汽车的距离&#xff0c;或者通过猜测球的速度并相应地定位手来接球。这些技能是通过经验和实践获得的。然而&#xff0c;由于涉及众多变量&#xff0c;预测天气或…

SpringCloudAlibaba微服务实战系列(二)Nacos配置中心

SpringCloudAlibaba Nacos配置中心 在java代码中或者在配置文件中写配置&#xff0c;是最不雅的&#xff0c;意味着每次修改配置都需要重新打包或者替换class文件。若放在远程的配置文件中&#xff0c;每次修改了配置后只需要重启一次服务即可。话不多说&#xff0c;直接干货拉…

NoSQL之 Redis配置与优化

文章目录 一.关系数据库与非关系型数据库1.关系型数据库2.非关系型数据库3.关系型数据库和非关系型数据库区别4.非关系型数据库产生背景 二.Redis简介1.了解Redis2.Redis 具有以下几个优点3.Redis为何这么快 三.Redis 安装及应用1.Redis 安装部署2.Redis 命令工具2.1 redis-cli…

会点C++还需要再学Python吗?

提到的C、数据结构与算法、操作系统、计算机网络和数据库技术等确实是计算机科学中非常重要的基础知识领域&#xff0c;对于软件开发和计算机工程师来说&#xff0c;它们是必备的核心知识。掌握这些知识对于开发高性能、可靠和安全的应用程序非常重要。Python作为一种脚本语言&…

运动蓝牙耳机什么牌子的好用、最好用的运动蓝牙耳机推荐

音乐是运动的灵魂&#xff0c;而一款优秀的运动耳机则是让音乐与我们的身体完美融合的关键。今天&#xff0c;我推荐五款备受运动爱好者喜爱的耳机&#xff0c;它们以卓越的音质、舒适的佩戴和出色的稳定性能脱颖而出&#xff0c;助你在运动中创造最佳状态。 1、NANK南卡Runne…

安全第一天

1. 编码 1.1 ASCLL编码 ASCII 是基于拉丁字母的一套电脑编码系统&#xff0c;主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准&#xff0c;并等同于国际标准ISO/IEC 646。 1.2 URL编码 URL&#xff1a;&#xff08;统一资源定位器、定位地址&#xff0c;俗称网页…

k8s常见的资源对象使用

目录 一、kubernetes内置资源对象 1.1、kubernetes内置资源对象介绍 1.2、kubernetes资源对象操作命令 二、job与cronjob计划任务 2.1、job计划任务 2.2、cronjob计划任务 三、RC/RS副本控制器 3.1、RC副本控制器 3.2、RS副本控制器 3.3、RS更新pod 四、Deployment副…

概率论的学习和整理21:用EXCEL来做假设检验(未完成草稿)

目录 1 EXCEL可以用来做假设检验 1.1 如何打开 数据分析 和 规划求解 1.2 EXCEL里关于正态分布的准备知识 2 基本的假设检验 2.1 最基本的假设检验&#xff0c;单边的Z检验 2.1 双样本F检验 2.1.1 例题 2.1.2 进行F检验之前需要满足一些假设条件 2.1.3 计算步骤 2.1…

MySQL 数据抽稀 每分钟取一条

假如原始数据为每5秒一个数据&#xff0c;现在想展示为每4分钟一条数据&#xff0c;先按照分钟数把除以4余数为0的行选出来&#xff0c;在按照 年月日 时分&#xff0c;做组内排序&#xff08;窗函数ROW_NUMBER&#xff09;&#xff0c;最后再拿出序号为1的行。 WITH data_01 …

网工实操基础学习23.07.05

1.交换机&#xff0c;路由器 交换机的作用是链接同一个网络下的所有设备&#xff0c;如果有无线设备加入&#xff0c;需要添加AP&#xff08;无线接入点&#xff09;设备在交换机层次上 路由器的作用是将不同网络下的设备链接 2.IP地址 划分网段&#xff1a;网络位、网段、…