Python3 __name__ 与 __main__
Python3 __name__
与 __main__
🎯 学习目标
掌握 Python 中模块的 __name__
属性和 __main__
的作用机制,理解如何利用这一机制实现模块的可执行性控制。能够在开发中编写既能被导入又能作为脚本运行的模块,并理解其在实际项目中的应用。
🔑 核心重点
分类 | 内容 |
---|---|
__name__ 属性 |
每个模块都有一个内置变量 __name__ ,表示当前模块名称 |
__main__ 特殊值 |
当模块作为主程序运行时,其 __name__ 值为 '__main__' |
可执行性控制 | 利用 if __name__ == '__main__': 实现模块是否直接运行逻辑 |
应用场景 | 编写可测试、可运行的模块;构建命令行工具 |
📚 详细讲解
一、什么是 __name__
?
每个 Python 模块(.py
文件)在加载时都会有一个内置属性 __name__
,它用于标识该模块的名字。
- 如果你直接运行这个模块(如通过命令行或 PyCharm 运行),它的
__name__
就是"__main__"
。 - 如果这个模块被其他模块导入,则它的
__name__
是模块名(即文件名去掉.py
后缀)。
✅ 示例:
创建文件 hello.py
:
# hello.py
print("模块的 __name__ 是:", __name__)
情况1:直接运行
python hello.py
输出:
模块的 __name__ 是: __main__
情况2:被导入
创建 main.py
:
# main.py
import hello
运行:
python main.py
输出:
模块的 __name__ 是: hello
二、if __name__ == "__main__":
的作用
这是 Python 中常见的模式,用于判断当前模块是否被直接运行。
✅ 示例:
# greet.py
def say_hello():
print("Hello, world!")
if __name__ == "__main__":
say_hello()
- 直接运行
greet.py
:会输出Hello, world!
- 导入
greet
模块:不会自动调用say_hello()
📌 这种方式非常适合为模块添加自测代码或命令行接口。
三、模块化编程中的最佳实践
- 每个功能模块都应包含
if __name__ == "__main__":
部分,用于调试或演示。 - 主程序模块可以不使用此结构,但建议保留清晰的入口点。
- 可以在
__main__
块中解析命令行参数,构建 CLI 工具。
✅ 示例:带命令行参数的模块
# calculator.py
import sys
def add(a, b):
return a + b
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: python calculator.py <num1> <num2>")
else:
num1 = float(sys.argv[1])
num2 = float(sys.argv[2])
print(f"Sum: {add(num1, num2)}")
运行方式:
python calculator.py 3 5
输出:
Sum: 8.0
⚠️ 注意事项
__name__
是只读属性,不能修改。- 不要在模块中频繁使用
if __name__ == "__main__":
来执行复杂逻辑,保持简洁。 - 若模块被多次导入,其
__name__
始终不变。 - 使用相对导入时注意包结构,避免误判
__name__
。
🧪 实际案例分析
📌 场景:构建一个可执行的单元测试模块
目录结构:
project/
├── math_utils.py
└── test_math_utils.py
math_utils.py
内容:
def square(x):
return x * x
def cube(x):
return x * x * x
if __name__ == "__main__":
import doctest
doctest.testmod()
你可以这样运行:
python math_utils.py -v
输出示例:
Trying:
square(2)
Expecting:
4
ok
...
📌 优势:
- 模块本身自带测试样例,便于维护
- 无需额外测试脚本即可验证功能
- 提高模块的可移植性和健壮性
🧩 拓展练习(动手实践)
- 创建一个模块
utils.py
,定义几个常用函数,并加入if __name__ == "__main__":
来测试它们。 - 编写一个能接收命令行参数的模块,计算斐波那契数列并打印。
- 在
__main__
块中引入argparse
构建更复杂的命令行接口。 - 修改你的模块,在导入时打印日志,而在主程序运行时执行特定操作。
- 结合
unittest
或pytest
框架,为你的模块编写测试用例并嵌入到__main__
中。
📚 推荐阅读
- Python 官方文档 - Modules
- Real Python - Understanding if name == "main"
- 《流畅的 Python》第 16 章 - 模块与包
- 菜鸟教程 - Python 模块
- 廖雪峰 Python 教程 - 模块
🧭 下一步建议
- 下一章学习内容:《Python3 包与发布》
- 学习如何将多个模块组织成包
- 掌握使用
setuptools
打包发布模块 - 探索上传到 PyPI 并分享你的模块
- 理解依赖管理、虚拟环境等进阶知识
如果你希望我为你提供:
__name__
与__main__
原理图解 PDF- 更多实战练习题(如构建 CLI 工具、模块自测系统等)
- 视频教学资源推荐(中文讲解)
- 如何结合
argparse
和logging
构建专业级命令行工具
欢迎随时告诉我 😊