21 python __name__ 与 __main__
在办公室里,每个员工都有自己的工牌,上面写着姓名和部门。
一、__name__:模块的名字
Python 模块也有类似的 "工牌"——__name__
属性,它记录了模块的身份:
- 直接运行时 →
__name__ = "__main__"
(相当于员工独立工作时的身份)- 被其他模块导入时 →
__name__ = "模块名"
(相当于员工被借调到其他部门时的身份)
二、__main__:独立工作的标志
当模块作为主程序运行时,Python 会将__name__
设为"__main__"
,这相当于员工在自己的工位独立完成任务。
在前面我们会编写自己的模块和包,但是要测试这个模块和包,又需要再编写一个py文件,有没有办法我在模块里就进行测试了呢,这就要提到__main__了。
比如我在前面写的自定义模块里运行,是没有任何执行的,但是我将document_utils.py改成下面的样子:
def print_document(doc_name):
print(f"正在打印文档: {doc_name}")
def main():
print_document("report.docx")
if __name__ == '__main__':
main()
当我们在该模块运行时,会调用main函数,而在外部进行导入时就不会调用main函数,这样,我们就可以在我们的模块里测试我们的功能函数。
我们还可以修改成这样,当外部调用时会有提示。
def print_document(doc_name):
print(f"正在打印文档: {doc_name}")
def main():
print_document("report.docx")
if __name__ == '__main__':
main()
else:
print("模块document_utils已被加载...")
三、为什么需要双重身份
- 代码复用 → 模块可以同时作为工具库和独立脚本
- 测试方便 → 开发时直接运行测试,集成时隐藏测试代码
- 职责分离 → 独立逻辑与工具函数分开,避免混乱
四、最佳实践:模块开发规范
所有可执行代码放入if __name__ == "__main__"
避免模块被导入时意外执行代码。
测试代码与业务逻辑分离
def 生成报表():
# 业务逻辑
pass
if __name__ == "__main__":
生成报表() # 仅独立运行时生成报表
添加初始化提示
if __name__ == "__main__":
print("开始独立执行报表生成")
else:
print("报表模块已导入,可随时调用")
五、常见问题解答
-
如果模块没有
if __name__
块?
→ 所有代码在导入时都会执行(类似员工被借调时还在做自己的事) -
可以有多个
if __name__
块吗?
→ 可以,但建议集中管理,避免代码分散 -
如何调试被导入的模块?
→ 在else
块中添加调试代码,或使用日志工具