main 不是入口——在它之前还有启动代码:备好栈、传好参数、初始化运行环境;结束后也由它收尾。
8.4 拼出了完整链条,这一节补上链条最前面那一小段。
一、main 不是第一个跑的
一个常见的误会是【程序从 main 开始跑】。 其实在 main 之前,还有一段启动代码要先执行。 它的活儿不难理解,但一件都不能少——少了任何一件,你的 main 就跑不起来。 所以严格地说:main 是被调用的,不是被启动的。
二、启动代码做三件事
备好环境——把栈准备好,把全局数据初始化好。 传好参数——把命令行参数整理成 main 能接着的形式。 调用并收尾——调 main,等它返回,然后刷新输出、把退出码报给系统。 换句话说:跟系统打交道的那部分活儿,全被它包了。
三、Python 里的同一个套路
Python 没有 main 函数,但有一个一模一样的机制:__name__。
被别的文件 import 时,__name__ 是模块名;被直接运行时,它变成 __main__。
所以那句最常见的写法:if __name__ == "__main__":
它的意思就是:只有当我是被直接跑的那个文件时,才执行下面这段。
原理和 C 的启动代码一样:入口由环境决定,不由你决定。
四、为什么要有这一段
因为它把【跟环境有关的那部分琐事】集中到了一处。 如果每个程序都要自己准备栈、自己接收参数、那写程序的人会被这些杂事淹没。 把它们抽出来放进启动代码,你的代码就只管业务逻辑。 这种【把和平台打交道的事抽到一边】的做法,贯穿整本书——从驱动到虚拟机,都是同一个思路。
五、动手 Demo:启动代码与库文件
一个常见的误会是【程序从 main 开始跑】。 其实在它之前还有一段启动代码要先跑。
import sys, os
print("被 import 进来时 math.__name__ = math")
print("被直接运行时 __name__ 会变成 __main__")
print("命令行第一个参数 ", os.path.basename(sys.argv[0]))
# if __name__ == "__main__":
# 只有被直接运行时才走这里
实跑输出:
--------------------------------------------------------------------
启动代码与库文件
--------------------------------------------------------------------
一个常见的误会是【程序从 main 开始跑】。
**其实 main 不是入口**——在它之前还有一段**启动代码**要先跑。
顺序 谁在跑 做什么
-------------------------------------------------------------
先 启动代码 准备好栈、把参数收拢好、初始化运行环境
再 启动代码 调 main,把控制权交给你的代码
后 main 执行你写的那部分逻辑
最后 启动代码 收尾:刷新输出、返回退出码
Python 里也有同一个套路——**模块先被执行,其中 `__name__` 决定它自己是谁:**
被 import 进来时 math.__name__ = math
被直接运行时 __name__ 会变成 __main__
命令行第一个参数 _demos_27.py
所以那句最常见的写法:
if __name__ == "__main__":
**它的意思就是【只有当我是被直接跑的那个文件时,才执行下面这段】。**
被别的文件 import 时,`__name__` 变成模块名,那段就不执行了。
**道理和 C 语言的启动代码一样:入口那件事由环境决定,不由你决定。**
入口由环境决定,不由你决定:开机的第一段代码永远是启动代码。
Python 里用 __name__ 判断,C 语言里则由启动代码来调 main。
30 秒实验
- 把一段代码写进 if name == "main" 里,分别用直接运行和 import 两种方式试。
- 想一想:如果启动代码不准备栈,函数调用会发生什么。
常见误区
- 以为 main 是第一个执行的。启动代码在它之前。
- 以为 name 只是个小技巧。它就是【我是不是入口】这个判断本身。
自测三问(点开对答案)
1. main 之前还有谁在跑? —— 启动代码——准备栈与全局数据、整理参数,然后才调用 main。 2. 启动代码在 main 返回后还做什么? —— 收尾:刷新输出、把退出码报给操作系统。 3. Python 里对应的机制是什么? —— __name__:被直接运行时是 __main__,被 import 时是模块名。- ☐ 下一节(8.6 DLL文件与导入库)
相关笔记
- 仅靠编译无法得到可执行文件 — 链接是怎么接上的
- DLL文件与导入库 — 库文件的两种接法
- BIOS与引导装入程序 — 另一场接力赛
- 🔵 计算机基础 · 索引 — 硬件底层的入门课
- ⚙️ 程序是怎样跑起来的 · 索引