Skip to content

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 语句下的代码块。 当脚本被导入时,该代码块会被跳过。

python
if __name__ == '__main__':
    # 这里的代码只会在脚本直接运行时执行
    ...要执行的代码...

为什么要有这种机制?

这种机制非常有用,因为它允许你在模块中包含一些测试代码或演示代码,这些代码只在你直接运行该模块时才会被执行。当你将该模块导入到其他程序中时,这些测试代码不会干扰你的主程序。

示例:multi.py 模块

让我们通过一个例子来更好地理解 __name__ 的作用。假设我们有一个名为 multi.py 的模块,它包含一个 multiply 函数,用于计算两个数的乘积。

版本 1:没有 if __name__ == '__main__'

python
# 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 被加载了!") 和后面的输入及计算代码都会被执行。

python
>>> import multi
multi.py 被加载了!
输入 a: 4
输入 b: 5
乘积是: 20
>>> multi.multiply(2, 3)
6

可以看到,导入 multi 模块时,它自动执行了输入和计算操作,这可能不是我们期望的。

版本 2:使用 if __name__ == '__main__'

python
# 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

bash
$ python multi.py
multi.py __name__ 是: __main__
multi.py 作为主程序运行
输入 a: 4
输入 b: 5
乘积是: 20

当我们直接运行 multi.py 时,__name__ 的值为 '__main__',所以 if 语句下的代码块会被执行。

在 Python 解释器中导入:

python
>>> import multi
multi.py 的 __name__ 是: multi
>>> multi.multiply(2, 3)
6

当我们导入 multi 模块时,__name__ 的值为 'multi',所以 if 语句下的代码块不会被执行。 只有 multiply 函数被成功导入,我们可以正常调用它。

if __name__ == '__main__': 结构是编写 Python 模块时的一个重要技巧。 它可以让你轻松地创建既可以作为独立脚本运行,又可以作为模块导入的代码,提高代码的灵活性和可重用性。