当Python遇到“真假美猴王”:__main__ 与 __mp_main__ 的恩怨情仇
01 深夜的报错,像极了爱情
凌晨 2:30,我正用 NiceGUI 撸一个颜值报表,代码写完,帅气地一按回车——
You must call ui.run() to start the server.
???
我明明写了 ui.run() 啊!难道 Python 也熬夜熬到失忆?
02 真入口 vs 假入口:导演,他加戏!
原来,在 Windows 的舞台上,Python 的 multiprocessing 喜欢搞“替身文学”:
| 场景 | __name__ 值 |
身份 |
|---|---|---|
| 你双击脚本 | "__main__" |
真·入口 |
| multiprocessing 子进程重新 import 脚本 | "__mp_main__" |
替身·入口 |
导演 NiceGUI 喊:
“只要你是主角,就能启动服务器!”
于是替身不服:
“我穿一样的衣服,为啥不让我开机?”
结果真入口被 if __name__ == "__main__" 拦在门外,替身也进不来,服务器直接罢工。
03 __main__ 到底是干嘛的?
一句话:“防止你写的烂代码在被人 import 时原地爆炸。”
举个栗子:
# cat_launcher.py
def meow():
print("喵~")
# 测试代码
if __name__ == "__main__":
meow() # 只有直接运行才会喵喵叫
- 直接运行:
python cat_launcher.py→ 喵喵喵 - 被别人 import:
import cat_launcher→ 安静如鸡
这就是“入口守卫” ——
让脚本既能当库,又能当工具,不尴尬。
04 Windows 的彩蛋:替身文学现场
在 Windows 上,multiprocessing 需要“重启”一个 Python 进程,于是:
- 重新 import 你的脚本;
- 把
__name__改成"__mp_main__"; - 如果你的守卫只认
"__main__",替身就被挡在门外; - NiceGUI 检测不到服务器,直接甩锅报错。
05 官方给出的两种“和解方案”
方案 A:拆门——干脆不要守卫
ui.run() # 谁 import 我,谁直接开服务器
缺点:你室友半夜 import 你一下,服务器被惊醒。
方案 B:发双通行证——替身也放行
if __name__ in {"__main__", "__mp_main__"}:
ui.run()
真入口 & 替身一起进门,世界和平。
06 彩蛋:一句话记住
写脚本时,
__main__是“我来主演”;
multiprocessing 时,__mp_main__是“我替主演”。
两个都得让进门,否则服务器掀桌子。
07 正解
from nicegui import ui
ui.label('Hello NiceGUI')
if __name__ in {"__main__", "__mp_main__"}:
ui.run()
下次再遇到“替身文学”,记得给替身也买张门票,别让服务器一个人演独角戏!

浙公网安备 33010602011771号