Python脚本变身模块:__name__
变量的妙用
Python 模块不仅仅是包含函数和变量定义的代码集合。它们还可以包含可执行的代码块。 关键在于理解 __name__
这个特殊变量,它决定了模块中的代码在何时以及如何运行。
__name__
是什么?
__name__
是一个内置变量,每个 Python 模块都有。它的值取决于模块是如何被使用的:
- 直接运行脚本: 当你直接通过命令行运行一个 Python 脚本 (例如
python my_script.py
) 时,该脚本的__name__
变量会被设置为字符串'__main__'
。 - 作为模块导入: 当你将一个 Python 文件作为模块导入到另一个脚本中 (
import my_script
) 时,被导入模块的__name__
变量会被设置为该模块的名称(也就是文件名,不包含.py
后缀)。
if __name__ == '__main__':
的作用
这个条件语句是 Python 中一个常用的技巧,它允许你编写既可以作为独立脚本运行,又可以作为模块导入的代码。只有当脚本被直接运行时,才会执行 if
语句下的代码块。 当脚本被导入时,该代码块会被跳过。
if __name__ == '__main__':
# 这里的代码只会在脚本直接运行时执行
...要执行的代码...
为什么要有这种机制?
这种机制非常有用,因为它允许你在模块中包含一些测试代码或演示代码,这些代码只在你直接运行该模块时才会被执行。当你将该模块导入到其他程序中时,这些测试代码不会干扰你的主程序。
示例:multi.py
模块
让我们通过一个例子来更好地理解 __name__
的作用。假设我们有一个名为 multi.py
的模块,它包含一个 multiply
函数,用于计算两个数的乘积。
版本 1:没有 if __name__ == '__main__'
# multi.py (版本 1)
def multiply(a, b):
"""返回 a 和 b 的乘积."""
return a * b
# 这部分代码无论导入还是直接运行都会执行
print("multi.py 被加载了!")
f = int(input("输入 a: "))
s = int(input("输入 b: "))
print("乘积是:", multiply(f, s))
在这个版本中,无论你是直接运行 multi.py
,还是将其导入到另一个模块中,print("multi.py 被加载了!")
和后面的输入及计算代码都会被执行。
>>> import multi
multi.py 被加载了!
输入 a: 4
输入 b: 5
乘积是: 20
>>> multi.multiply(2, 3)
6
可以看到,导入 multi
模块时,它自动执行了输入和计算操作,这可能不是我们期望的。
版本 2:使用 if __name__ == '__main__'
# multi.py (版本 2)
def multiply(a, b):
"""返回 a 和 b 的乘积."""
return a * b
print("multi.py 的 __name__ 是:", __name__) # 观察 __name__ 的值
if __name__ == '__main__':
print("multi.py 作为主程序运行")
f = int(input("输入 a: "))
s = int(input("输入 b: "))
print("乘积是:", multiply(f, s))
在这个版本中,我们将输入和计算代码放在了 if __name__ == '__main__':
块中。
直接运行 multi.py
:
$ python multi.py
multi.py 的 __name__ 是: __main__
multi.py 作为主程序运行
输入 a: 4
输入 b: 5
乘积是: 20
当我们直接运行 multi.py
时,__name__
的值为 '__main__'
,所以 if
语句下的代码块会被执行。
在 Python 解释器中导入:
>>> import multi
multi.py 的 __name__ 是: multi
>>> multi.multiply(2, 3)
6
当我们导入 multi
模块时,__name__
的值为 'multi'
,所以 if
语句下的代码块不会被执行。 只有 multiply
函数被成功导入,我们可以正常调用它。
if __name__ == '__main__':
结构是编写 Python 模块时的一个重要技巧。 它可以让你轻松地创建既可以作为独立脚本运行,又可以作为模块导入的代码,提高代码的灵活性和可重用性。