首页 后端开发 Python教程 Python 的内部工作原理

Python 的内部工作原理

Nov 04, 2024 pm 01:45 PM

Internal Working Of Python

这是完整的代码文件:代码

1.源代码

当您编写 Python 脚本时,它是人类可读的文本。这个源代码是一切的起点。

您的 Python 源代码以 .py 文件编写,是人类可读的。此代码定义了程序的功能,指定变量、函数、循环等。

2.编译为字节码(编译器)

当你运行Python程序时,第一步是将源代码编译为字节码。这是由 Python 解释器完成的:

  • 语法检查:确保没有语法错误。
  • 编译:将高级源代码转换为字节码,这是一种较低级别的、与平台无关的表示形式。该字节码通常驻留在 __pycache__ 目录中的 .pyc 文件中。
    • 编译器:Python 使用解释器,但它首先将源代码编译为称为字节码的较低级别形式。
  • 标记化:将代码分解为称为标记的小块(如关键字、运算符、标识符)。
  • 解析:分析标记以确保它们遵循 Python 的语法规则。
  • 控制流图(CFG):表示程序在执行过程中可能遍历的所有路径。
  • 字节码生成:将解析后的令牌转换为字节码,这是Python虚拟机(PVM)的一组指令。

Internal Working Of Python

让我们深入探讨一下。

Python 编译器:尽管 Python 被称为解释性语言,但它确实有一个编译步骤。详细内容如下:

标记化

  • 将代码分解为称为标记的小块(如关键字、运算符、标识符)。
  1. 源代码:从您编写的代码开始。
  2. 分词器 (Lexer):这会将源代码分解为称为标记的较小部分,例如关键字(for、if)、运算符(、-)、标识符(变量名称)和文字(例如数字或字符串) .
  3. 解析:分析标记以确保它们遵循 Python 的语法规则。
  4. 语法分析:解析器获取这些标记并根据 Python 的语法规则检查它们。
  5. 解析树:从标记构建树结构,表示代码的语法结构。
  6. 语义分析:确保代码在数据类型、范围和其他特定于上下文的规则方面有意义。
  7. 控制流图(CFG):表示程序在执行过程中可能遍历的所有路径。
    • 控制流图:表示代码执行过程中可能采取的所有可能路径。
    • 节点和边:每个节点代表一个基本代码块,边代表从一个块到另一个块的控制流。
  8. 字节码生成:将解析后的令牌转换为字节码,这是Python虚拟机(PVM)的一组指令。
    • 字节码是源代码的更紧凑、较低级别的表示形式,并针对执行进行了优化。它独立于平台,这意味着它可以在任何具有兼容 PVM 的系统上运行。
    • 字节码:解析后的代码被转换为字节码,一种较低级别的、与平台无关的表示。
    • 指令集:该字节码是Python虚拟机(PVM)可以执行的一组指令。字节码存储在 __pycache__ 目录中的 .pyc 文件中,以加快将来的执行速度。

3.加载字节码(字节码)

编译后,Python 虚拟机加载字节码:

  • 从缓存中读取:如果字节码之前已编译且未更改,则从缓存(__pycache__)中读取。这通过跳过编译步骤来加快执行速度。
    • 字节码已加载到内存中,准备执行。然后字节码由 PVM 执行,解释指令以执行程序的任务。

4.由 PVM (PVM) 执行

PVM 现在解释并执行字节码:

  • 指令执行:PVM 读取每个字节码指令并执行它。每条指令对应一个特定的操作,例如加载值、执行算术或调用函数。
  • 内存管理:管理变量和对象的内存分配和释放。

Python 中的内存管理:

  1. 引用计数:Python 跟踪内存中对象的引用数量。当引用计数降至零时,可以回收该对象占用的内存。
  2. 对象分配:代码运行时在内存中创建 Python 对象(如整数、字符串、列表)。
  3. 垃圾收集:Python 有一个垃圾收集器,它通过释放不再使用的内存(即引用计数为零的对象)来帮助管理内存。
  4. 内存池:Python 使用内存池来更有效地分配小对象。这种池化有助于减少频繁分配和释放小块内存的开销。
  5. 内存优化:Python 应用各种优化来最小化内存使用,例如:
    • PVM 执行各种运行时优化以提高效率,例如某些实现(如 PyPy)中的即时 (JIT) 编译。
    • 重用小整数和内部字符串。
    • 有效管理数据结构(例如元组、列表、字典)。

示例

  • 字节码缓存:PVM 缓存已编译的字节码,以避免每次都重新编译源代码。这会加快后续运行的速度。
  • 常量折叠:这涉及在编译时而不是运行时简化常量表达式。例如,3 * 2 可能会预先计算为 6。

所以,总而言之:PVM 就像一个管弦乐队指挥,无缝地将字节码转换为计算机可以执行的操作。它的美妙之处在于,得益于 PVM,Python 代码是可移植的,无需修改即可在不同平台上运行。

我们如何查看字节码是否生成?

导入Python模块时,Python会将源代码编译为字节码并将其存储在__pycache__目录中。这有助于加快未来的导入速度,避免每次导入时都需要重新编译模块。

流程如下:

  • 首次导入:首次导入模块时,Python 会将 .py 文件编译为字节码。
  • pycache 目录:字节码存储在 __pycache__ 目录中,名称类似于 module_name.cpython-312.pyc。 # 312 是 Python 版本。
  • 后续导入:在后续导入时,Python 会检查 __pycache__ 目录中是否有已编译的字节码,如果源代码未更改,则使用它,从而加快导入过程。

例子:

我们有 byte.py。当我们在执行 byte.py 后从 hello_world.py 导入代码时,我们可以看到该特定文件夹中会有一个目录 __pycache__ ,并且我们可以看到 .pyc 文件:

from hello_world import greet

greet("Byte code")


登录后复制
登录后复制

通过使用 py_compile

py_compile模块,它允许你将Python源文件编译成字节码文件。这是一种加快未来运行脚本执行速度的便捷方法。

在 byte.py 中

import py_compile

py_compile.compile('hello_world.py')

登录后复制
登录后复制
  • py_compile 模块将 hello_world.py 编译为字节码。
  • 生成的字节码存储在 pycache 目录中,创建一个名为 hello_world.cpython-38.pyc (或类似文件,具体取决于您的 Python 版本)的文件。

生成字节码:

  • 执行整个脚本来生成字节码。这意味着任何顶级代码(例如 print("Hello, World!") 和 print("c"))都将在编译过程中运行。

生成的字节码:

  • 字节码包含所有函数、类和可执行语句,Python 使用它们来加速未来脚本的导入。

显示模块

Python 中的 dis 模块用于将字节码反汇编成更易读的形式。这可以帮助您了解 Python 代码在幕后的用途。它对于调试或了解 Python 的内部结构特别有用。

  • 在internal.py中我们有
from hello_world import greet

greet("Byte code")


登录后复制
登录后复制

输出

import py_compile

py_compile.compile('hello_world.py')

登录后复制
登录后复制
  • 程序首先导入 dis 模块,这是一个用于分析 CPython 字节码的强大工具。 CPython 是 Python 的默认实现,字节码是 Python 解释器的中间语言。
  • 接下来,我定义了一个名为greet的简单函数。该函数接受参数名称并打印出问候语。尽管函数本身非常简单,但 Python 底层发生的事情比表面上看起来更复杂。
  • disassemble_function 函数使用 dis.dis() 来反汇编greet函数。 dis.dis() 将 Python 函数转换为 Python 虚拟机实际执行的低级字节码。这个字节码是Python对greet函数的解释,更接近机器代码。
  • 当脚本调用 disassemble_function() 时,控制台输出显示我们的greet 函数的字节码。

这是字节码告诉我们的内容:

  • LOAD_GLOBAL(0):此操作码用于加载全局变量,在本例中是打印函数。
  • LOAD_CONST(1):这会将常量值“Hello,”加载到堆栈上。
  • LOAD_FAST(0):此操作码将局部变量名称加载到堆栈上。
  • FORMAT_VALUE(0):这会格式化我们的名称字符串,准备将其插入到即将构建的字符串中。
  • BUILD_STRING(2):这采用堆栈上的前两个值(“Hello,”和名称)并构建最终字符串。
  • CALL_FUNCTION(1):这一行调用函数(我们加载到堆栈上的全局打印函数),参数计数位于括号中(我们有一个参数,即我们的格式化字符串)。
  • POP_TOP:这会删除堆栈顶部(上一次调用的结果,因为 print 返回 None)。
  • LOAD_CONST(0):不加载。
  • RETURN_VALUE:这是greet函数的返回值,由于没有明确的return语句,因此为None。
  • 本质上,字节码显示了Python执行我们的greet函数时执行的各个操作。理解这些指令对于开发人员理解 Python 如何执行代码、优化函数和管理资源至关重要 - 当我们运行 Python 代码时,所有这些都在幕后无缝地发生。

这不是一次令人愉快地深入 Python 机房的经历吗?继续编码并继续探索该语言引擎室的深度?!

以上是Python 的内部工作原理的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何解决Linux终端中查看Python版本时遇到的权限问题? 如何解决Linux终端中查看Python版本时遇到的权限问题? Apr 01, 2025 pm 05:09 PM

Linux终端中查看Python版本时遇到权限问题的解决方法当你在Linux终端中尝试查看Python的版本时,输入python...

如何在10小时内通过项目和问题驱动的方式教计算机小白编程基础? 如何在10小时内通过项目和问题驱动的方式教计算机小白编程基础? Apr 02, 2025 am 07:18 AM

如何在10小时内教计算机小白编程基础?如果你只有10个小时来教计算机小白一些编程知识,你会选择教些什么�...

在Python中如何高效地将一个DataFrame的整列复制到另一个结构不同的DataFrame中? 在Python中如何高效地将一个DataFrame的整列复制到另一个结构不同的DataFrame中? Apr 01, 2025 pm 11:15 PM

在使用Python的pandas库时,如何在两个结构不同的DataFrame之间进行整列复制是一个常见的问题。假设我们有两个Dat...

如何在使用 Fiddler Everywhere 进行中间人读取时避免被浏览器检测到? 如何在使用 Fiddler Everywhere 进行中间人读取时避免被浏览器检测到? Apr 02, 2025 am 07:15 AM

使用FiddlerEverywhere进行中间人读取时如何避免被检测到当你使用FiddlerEverywhere...

什么是正则表达式? 什么是正则表达式? Mar 20, 2025 pm 06:25 PM

正则表达式是在编程中进行模式匹配和文本操作的强大工具,从而提高了各种应用程序的文本处理效率。

Uvicorn是如何在没有serve_forever()的情况下持续监听HTTP请求的? Uvicorn是如何在没有serve_forever()的情况下持续监听HTTP请求的? Apr 01, 2025 pm 10:51 PM

Uvicorn是如何持续监听HTTP请求的?Uvicorn是一个基于ASGI的轻量级Web服务器,其核心功能之一便是监听HTTP请求并进�...

哪些流行的Python库及其用途? 哪些流行的Python库及其用途? Mar 21, 2025 pm 06:46 PM

本文讨论了诸如Numpy,Pandas,Matplotlib,Scikit-Learn,Tensorflow,Tensorflow,Django,Blask和请求等流行的Python库,并详细介绍了它们在科学计算,数据分析,可视化,机器学习,网络开发和H中的用途

Python中如何通过字符串动态创建对象并调用其方法? Python中如何通过字符串动态创建对象并调用其方法? Apr 01, 2025 pm 11:18 PM

在Python中,如何通过字符串动态创建对象并调用其方法?这是一个常见的编程需求,尤其在需要根据配置或运行...

See all articles