news 2026/11/4 16:22:44

Python 到底是怎么运行的?从编译到执行的完整旅程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 到底是怎么运行的?从编译到执行的完整旅程

Python 发展历史

缘起:一个圣诞假期的"私活"项目

Python 的故事始于 1989 年的圣诞节。当时,荷兰程序员Guido van Rossum正在阿姆斯特丹的家中休假。为了打发无聊的假期时光,他决定启动一个个人项目:设计一门新的脚本解释语言。


初衷:继承 ABC 语言,填补 C 与 Shell 的空白

Guido van Rossum 的灵感并非凭空而来,而是源于他之前参与设计的一门名为 ABC 的教学语言。他认为 ABC 语言非常优美和强大,尤其适合非专业程序员,但其致命缺陷在于非开放性和扩展性差。因此,Guido van Rossum 创造 Python 的初衷非常明确:继承 ABC 语言简洁、易读、易用的核心特性;弥补其非开放、难扩展的缺陷,打造一门能与 C 语言交互的开放语言;填补 C 语言和 Shell 脚本之间的空白,既能快速编程,又具备强大功能。


命名:源自喜剧团体,而非"蟒蛇"

这是一个有趣的误会。很多人以为 Python 这个名字来源于「蟒蛇」,但实际上,Guido van Rossum 是一位英国喜剧团体 Monty Python 的忠实粉丝。为了体现这门新语言的趣味性和不严肃的风格,他直接从自己喜爱的喜剧《蒙提·派森的飞行马戏团》(Monty Python’s Flying Circus)中汲取灵感,将这门语言命名为 「Python」 。所以,Python 的 Logo 虽然是条蟒蛇,但它的名字其实源于一个喜剧团体。


灵魂:《Python 之禅》的哲学指引

Python 的灵魂,在于其独特的设计哲学——「Python 之禅」(The Zen of Python)。这套哲学由 Python 核心开发者蒂姆·彼得斯(Tim Peters)于 2004 年撰写,它并非一门技术,而是 19 条指导代码编写的格言,凝聚了 Python 社区的价值观。你可以在任何 Python 环境中输入import this来一窥其全貌。

  • 优美胜于丑陋(Beautiful is better than ugly.):代码不仅要功能正确,还要易于阅读和理解。优美的代码通常更易于维护和扩展。

  • 明确胜于隐晦(Explicit is better than implicit.):代码应明确表达意图,避免隐藏的逻辑或"魔法"行为,确保每段代码的行为都可追溯、可预测。

  • 简单胜于复杂(Simple is better than complex.):能用简单方法解决的问题,就不要引入不必要的复杂结构。

  • 可读性很重要(Readability counts.):这是 Python 的核心。代码是写给人看的,其次才是机器。良好的命名、注释和格式是必需的。

「Python 之禅」不仅适用于 Python,也为所有软件开发提供了通用智慧,它倡导的是一种清晰、简洁、务实的编程美学。


发展:从 0.9.0 到 3.0 的演进之路

1991 年,Guido van Rossum 发布了 Python 的第一个公开发行版(0.9.0)。这个版本已经包含了类、函数、异常处理等核心特性,奠定了 Python 的基础。

  • 1994 年:Python 1.0 版本发布,引入了函数式编程工具(如 lambda、map、filter),标志着语言走向成熟。

  • 2000 年:Python 2.0 发布,增加了垃圾回收机制和对 Unicode 的支持,生态开始蓬勃发展。

  • 2008 年:Python 3.0 发布,这是一次不向后兼容的重大升级,旨在解决 Python 2.x 中的设计缺陷,为 Python 的未来发展铺平了道路。

从 Guido van Rossum 的个人项目到如今的全球主流编程语言,Python 的成功源于其简洁的设计哲学、强大的社区支持和在 Web 开发、数据分析、人工智能等领域的广泛应用。


Python 代码执行过程

当你满怀期待地敲下python my_script.py,然后按下回车键,屏幕上最终呈现出你期望的结果。这看似简单的瞬间,背后却上演着一场由 Python 解释器精心编排的复杂“魔术”。今天,就让我们一同揭开这层神秘的面纱,深入探索 Python 代码从文本到执行的完整旅程,并看看它与其他语言有何不同。


第一步:编译?是的,你没听错!

很多人认为 Python 是纯粹的“解释型语言”,代码被一行行直接执行。这其实是一个常见的误解。实际上,在 Python 代码真正开始“跑”起来之前,它首先要经历一个编译阶段。

这个编译过程并非像 C/C++ 那样生成可以直接在 CPU 上运行的机器码,而是将我们编写的人类可读的源代码(.py文件),转换成一种名为**字节码(Bytecode)**的中间形态。

你可以把字节码想象成一种为 Python 虚拟机(PVM)量身定制的、与平台无关的低级指令集。它比源代码更接近机器,但又不依赖于任何特定的硬件或操作系统。

那么,这个编译过程是如何发生的呢?

  1. 词法分析(Tokenization):解释器首先会像阅读文章一样,将你的源代码字符串分解成一个个有意义的“单词”,我们称之为“标记(Token)”。比如x = 10会被分解为标识符x、赋值运算符=和数字常量10。

  2. 语法分析(Parsing):接着,解释器会检查这些标记的排列组合是否符合 Python 的语法规则。它会构建一棵抽象语法树(Abstract Syntax Tree, AST)。AST 是代码结构的树状表示,清晰地展现了代码的逻辑层次。如果代码中存在语法错误(比如漏了冒号或括号不匹配),程序就会在这一步戛然而止,并抛出SyntaxError。

  3. 生成字节码:一旦 AST 构建成功,Python 的编译器就会遍历这棵树,将其翻译成一系列的字节码指令。

一个有趣的细节:.pyc文件

你可能在项目目录中见过名为__pycache__的文件夹,里面存放着.pyc文件。这些就是编译后生成的字节码文件!Python 解释器会缓存它们,当下次导入同一个模块时,如果源代码没有改变,解释器就会直接加载这些.pyc文件,跳过耗时的编译步骤,从而加快程序的启动速度。


第二步:Python 虚拟机(PVM)登场

字节码生成之后,真正的主角——Python 虚拟机(Python Virtual Machine, PVM)——才正式登台。PVM 是一个用 C 语言实现的、基于栈的虚拟机。你可以把它想象成一个虚拟的、简化版的 CPU,它的任务就是读取并执行字节码指令。

PVM 的执行过程是一个巨大的循环,它不断地从字节码中取出指令,然后根据指令的含义执行相应的操作。

  • 基于栈的操作:PVM 内部维护着一个“操作数栈”。大多数指令都会与这个栈交互。例如,LOAD_CONST指令会将一个常量值压入栈顶,而BINARY_ADD指令则会从栈顶弹出两个值,将它们相加,再把结果压回栈中。

  • 逐条执行:PVM 就这样一条接一条地执行字节码,完成变量赋值、函数调用、循环控制等各种任务。当遇到函数调用时,PVM 会创建一个新的“栈帧(Frame)”来管理该函数的局部变量和执行上下文,函数执行完毕后,这个栈帧就会被销毁。


第三步:与操作系统握手

PVM 执行的字节码指令本身并不能直接操作硬件。当程序需要进行文件读写、网络通信或在屏幕上打印内容时,PVM 会调用底层的 C 库函数,这些 C 函数再与操作系统(如 Windows、Linux、macOS)进行交互,最终由操作系统调度硬件资源来完成实际工作。

例如,当你执行print("Hello, World!")时,PVM 会执行一系列字节码来准备字符串和调用print函数,最终这个调用会传递给操作系统的标准输出接口,将文本显示在你的终端上。


一个无法绕开的“角色”:全局解释器锁(GIL)

在讨论 Python 执行时,有一个话题总是绕不开,那就是全局解释器锁(Global Interpreter Lock,GIL)。

GIL 是 CPython(最常用的 Python 解释器)中的一个机制,它确保在任何时刻,只有一个线程在执行 Python 字节码。这主要是为了简化 CPython 的内存管理(尤其是引用计数机制),避免多线程同时修改对象时出现数据竞争。

然而,GIL 也带来了一个广为人知的“副作用”:在 CPU 密集型任务中,Python 的多线程并不能真正利用多核 CPU 的优势,有时甚至可能比单线程更慢。这也是为什么在处理计算密集型任务时,我们更推荐使用多进程(multiprocessing)而非多线程。


Python vs. 其他语言:一场执行模式的较量

为了更深刻地理解 Python 的执行模式,我们不妨将它与编译型语言(如 C/C++)和另一种混合型语言(如 Java)做个对比。

Python vs. C/C++:编译型与“混合型”的碰撞

  • C/C++(纯编译型):C/C++ 代码需要由编译器(如 GCC)一次性全部翻译成特定平台的机器码,生成一个独立的可执行文件(如 Windows 下的.exe)。这个文件可以直接被 CPU 执行,因此速度极快。但缺点是,这个.exe文件无法在其他操作系统上运行,跨平台性差。这就像把一本英文书完整地翻译成了中文并印刷成册,读者(CPU)可以直接阅读,但这本书只能在特定地区发行。

  • Python(混合型):Python 则采用“先编译成字节码,再解释执行”的模式。字节码是平台无关的,可以在任何安装了 Python 解释器的系统上运行,实现了“一次编写,到处运行”。但代价是,PVM 需要逐条解释字节码,执行效率通常低于 C/C++。这就像同声传译,演讲者(代码)说一句,翻译官(PVM)就立刻翻译一句给听众(CPU)听,虽然灵活,但总有一点点延迟。

Python vs. Java:殊途同归的“中间路线”

有趣的是,Python 和 Java 在执行模式上非常相似,都属于“编译+解释”的混合型。

  1. Java:.java源代码首先被编译成.class字节码文件,然后由 Java 虚拟机(JVM)加载并执行。JVM 同样可以选择解释执行,或者使用 JIT(即时编译器)将频繁执行的"热点代码"编译成本地机器码,以提升性能。

  2. Python:.py源代码被编译成.pyc字节码文件,然后由 PVM 解释执行。标准的 CPython 解释器主要是解释执行,但也有像 PyPy 这样的实现引入了 JIT 技术来加速。

PyPy 是什么?
PyPy 是 Python 解释器的另一种实现,核心特色是集成了JIT(即时编译器,Just-In-Time Compiler)。它会在程序运行过程中,把频繁执行的热点字节码动态编译成本地机器码,这样就不需要每次都逐条解释,从而大幅提升运行速度。对于CPU密集型计算,PyPy 通常比 CPython 快几倍甚至几十倍。但缺点是兼容性不如 CPython,部分 C 扩展不支持,因此开发阶段一般还是使用 CPython。

可以说,Python 和 Java 都巧妙地选择了在开发效率(跨平台、动态性)和执行效率之间取得平衡的"中间路线"。

以上流程图概括了 Python 从源码到执行的全过程。下面将 Python 与 C/C++、Java 的执行模式做横向对比:


Python 的类型系统定位

Python 是动态强类型语言。要准确理解这个概念,需要区分两个独立维度:

  • 类型检查时机:Python 是动态类型——变量不需要声明类型,类型在运行时确定。变量更像是一个「标签」,可以随时贴到不同类型的对象上。
  • 类型转换严格度:Python 是强类型——严禁隐式类型转换。"5" + 2会直接报TypeError,必须显式转换(如int("5") + 2)。

📌最常见的误区:「不需要声明类型」= 动态类型,≠ 弱类型。Python 是动态 + 强类型的组合。

💡深入阅读:关于编程语言的变量模型(标签 vs 盒子)、类型系统两大维度(动静 × 强弱)的完整辨析,以及 Java/C/JavaScript 等语言在四象限中的定位。详细可以查看动态 ≠ 弱类型:你把类型系统的两个维度搞混了


🤔 常见误区

  • 误区 1:“Python 变量不需要声明类型 → 所以是弱类型。”

    • 事实:不需要声明类型是「动态类型」而非「弱类型」。Python 是强类型,严禁隐式转换——"5" + 2会直接报TypeError。
  • 误区 2:“Python 是纯解释型语言,代码一行一行直接执行。”

    • 事实:Python 是「编译 + 解释」的混合型。源码先编译为字节码(.pyc),再由 PVM 逐条解释执行。
  • 误区 3:“GIL 让 Python 完全用不了多核。”

    • 事实:GIL 只影响 CPU 密集型的多线程。IO 密集型任务多线程依然有效,CPU 密集型可以用multiprocessing多进程方案。
  • 误区 4:“Python 太慢,不适合严肃项目。”

    • 事实:Python 在开发效率和执行效率之间做了权衡。大多数场景下开发效率优先级更高。性能瓶颈可以通过 C 扩展、PyPy 等方式解决。

🔗 相关资源

  • Python 入门基础——人工智能「超级引擎」
  • The Zen of Python (PEP 20)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/4 16:16:43

Mortiflix新手教程:从零安装本地AI视频工作室的5步完整指南

【免费下载链接】mortiflix-oss A motion design studio on your own machine: Claude makes the video step by step, you approve every stage. Bring your own Claude Code or API key. 项目地址: https://gitcode.com/gh_mirrors/mo/mortiflix-oss 点击查看 免费…

作者头像 李华
网站建设 2026/11/4 16:11:43

March7thAssistant 上手指南:3 步跑通星穹铁道日常自动化

March7thAssistant 上手指南:3 步跑通星穹铁道日常自动化 【免费下载链接】March7thAssistant 日常交给三月七,开拓留给你。《崩坏:星穹铁道》开源自动化助手。 项目地址: https://gitcode.com/gh_mirrors/ma/March7thAssistant March…

作者头像 李华
网站建设 2026/11/4 16:07:43

signature_pad 签名图片压缩避坑全解

signature_pad 签名图片压缩避坑全解 【免费下载链接】signature_pad HTML5 canvas based smooth signature drawing 项目地址: https://gitcode.com/gh_mirrors/si/signature_pad 上线第一个月,订单系统里用户提交的签名图片平均 200KB,CDN 带宽…

作者头像 李华