python中if __name__ == ‘__main__‘ 的作用再谈
python中if __name__ == '__main__' 的作用再谈
我原来的一篇博文:Python 中的 if __name__ == '__main__' 的作用https://blog.csdn.net/cnds123/article/details/116655291 已谈过这个问题,现在看来不全面,故再写此文。
python代码中使用中if __name__ == '__main__',是Python编程中的一个最佳实践,它提高了代码的模块化和可重用性,同时也提供了更好的代码组织结构。
__name__ 属性的本质
每个 Python 模块都内置有 __name__ 属性,该属性存储着模块的名称。
当模块直接作为主程序运行时,__name__ 的值会被设置为 '__main__'。
当模块被其他模块导入时, __name__ 的值是模块的导入名称,而非单纯的文件名。若模块结构为包层级(如 package/module.py),被导入时 __name__ 为 package.module(遵循 Python 的导入机制),示例:
文件路径 my_package/math_funcs.py 被导入时,__name__ 为 my_package.math_funcs。
直接运行脚本时,__name__ 为 __main__。
if __name__ == '__main__' 的作用
if __name__ == '__main__' 在Python中是一个常用的习惯用法,它的作用主要有以下几点:
1. 区分脚本执行与模块导入:
当直接运行该脚本时,__name__ 变量的值为 '__main__'。
当该脚本被作为模块导入时,__name__ 变量的值为模块名。
2. 控制代码执行:
可以将主要的执行代码放在这个条件语句下,确保只有在直接运行脚本时才执行这些代码。
当脚本被导入为模块时,这部分代码不会执行。
3. 模块测试:
可以在这个条件下编写测试代码,方便对模块进行单元测试。此方法适合临时测试或示例代码,若需复杂测试逻辑,建议使用 unittest 或 pytest 框架,将测试代码分离到独立文件中。
这样可以在不影响模块导入的情况下,为模块提供一些测试或示例代码。
4. 提高代码的可重用性:
将主要功能封装在函数中,然后在 if __name__ == '__main__' 下调用这些函数。
这样既可以直接运行脚本,又可以在需要时将脚本作为模块导入并使用其中的函数。
在开发过程中,我们经常需要测试代码段。通过if __name__ == '__main__',我们可以方便地在模块底部添加测试代码,而不用担心它们在模块被导入时执行。
示例代码
一个简单示例,源码:
def greet(name):return f"Hello, {name}"if __name__ == "__main__":# 仅在直接运行时执行user_name = input("Enter your name: ")print(greet(user_name))
直接运行:输入名字后会输出问候语。
被导入使用时:仅暴露 greet 函数,不会执行输入和打印操作。
又如:
# math_functions.py
def add(a, b):return a + bdef subtract(a, b):return a - bif __name__ == '__main__':print("Testing add function:")print(add(1, 2)) # Should output 3print("Testing subtract function:")print(subtract(5, 3)) # Should output 2
当该模块被其他脚本导入时的行为,例如:
# other_script.py
import math_functions
print(math_functions.add(10, 20)) # 正常调用函数,不会执行测试代码
由此可知,其作用:
这个惯用语的使用分离测试代码与业务逻辑。
可以直接在模块底部编写测试代码,并将其置于条件判断内部。这样一来,当模块作为主程序运行时,能够直接进行自测;而当模块被导入时,测试代码不会影响主程序,测试代码仅在自身运行时执行,避免导入时执行不必要的代码
测试代码等仅在模块自身运行时执行,而在被导入时不会干扰其他程序的逻辑,使模块能够专注于提供功能函数,提升代码的健壮性和可维护性,便于复用。
特别提示,在大型项目中,可能存在多个模块包含 if __name__ == '__main__' 条件块,用于各自的独立测试或入口逻辑,这是允许的。