📌  相关文章
📜  if __name__ == “__main__”: 做什么?(1)

📅  最后修改于: 2023-12-03 15:15:47.438000             🧑  作者: Mango

if name == “main”:

如果你曾经接触过Python的模块,就一定见过“if name == “main”:”的用法。这个特殊的if语句块在Python中有着特别的用途。在本文中,我们将介绍if name == “main”:这个用法的作用和原理,并解释如何在代码中使用它。

作用

在Python中,每个模块都有一个内置的__name__属性,这个属性用来标识模块的名字。当一个模块被执行时,Python解释器会首先把模块名字存储在__name__变量中。

当我们在命令行或其他Python模块中执行一个模块时,Python解释器会自动把当前模块的__name__属性设置为”main”(主模块)。这样,我们就可以利用if name == “main”:这个特殊的条件语句,来判断这个模块是被导入还是直接运行。

原理

我们先来看一下一个简单的Python程序,这个程序包含了一个函数和一个if name == “main”:语句块:

def my_function():
    print("This is my function.")
 
if __name__ == "__main__":
    my_function()

当我们在命令行中运行这个程序时,Python解释器会把程序所在的模块名字存储在__name__变量中,并执行程序。

如果我们把这个程序保存为my_module.py文件,并在另一个Python脚本中使用import导入这个模块,那么if name == “main”:语句块中的代码就不会被执行。

这是为什么呢?因为在导入模块的过程中,Python解释器会把模块名字存储在__name__变量中,并执行模块内的代码。此时,if name == “main”:语句块返回的是False,所以里面的代码不会被执行。

如何使用

现在你已经了解了if name == “main”:语句块的作用和原理。那么在代码中如何使用呢?下面我们来看几个例子。

例子1:测试模块

如果你写过Python模块,你就会知道,测试模块是用来测试模块中的函数是否正确的。下面是一个简单的测试模块:

def add(a, b):
    return a + b
 
def test_add():
    assert add(1, 2) == 3
    assert add('Hello, ','world!') == 'Hello, world!'
 
if __name__ == "__main__":
    test_add()

在这个测试模块中,我们定义了一个add()函数和一个test_add()函数。add()函数用来计算两个数的和或者连接两个字符串,而test_add()函数则用来测试add()函数是否正确。

当我们在命令行中执行这个测试模块时,Python解释器会把程序所在的模块名字存储在__name__变量中,并执行测试模块中的代码。因为if name == “main”:语句块返回的是True,所以test_add()函数会被执行。

例子2:运行脚本

下面是一个简单的Python脚本,它用来连接两个字符串并输出结果:

def concatenate(a, b):
    return a + b
 
if __name__ == "__main__":
    print(concatenate('Hello, ','world!'))

当我们在命令行中执行这个脚本时,Python解释器会把程序所在的模块名字存储在__name__变量中,并执行脚本中的代码。因为if name == “main”:语句块返回的是True,所以concatenate()函数会被执行并输出结果。

例子3:多线程

在多线程编程时,if name == “main”:语句块通常用来防止子线程执行父线程中的代码。这是因为子线程执行时,它会把当前模块的__name__属性设置为父线程的模块名字,这样一来,就可能会执行父线程中的代码。

下面是一个简单的例子,它说明了如何使用if name == “main”:语句块来避免多线程中的问题:

import threading
 
def worker():
    print("Worker")
 
if __name__ == "__main__":
    threads = []
 
    for i in range(5):
        t = threading.Thread(target=worker)
        threads.append(t)
        t.start()

在这个例子中,我们首先导入了threading模块,然后定义了一个worker()函数。worker()函数的作用是输出一条信息,以便我们在控制台上查看多线程的执行情况。

在if name == “main”:语句块中,我们定义了5个线程,并把它们放入一个列表中,然后启动它们。这样做是为了防止子线程执行父线程中的代码,从而避免出现不必要的问题。

总结

在Python中,if name == “main”:语句块是一个非常有用的特性。它可以让我们在程序中判断当前模块是被导入还是直接运行,并根据需要执行不同的代码。在编写Python程序时,我们应该充分利用这个特性,从而编写出更加健壮可靠的代码。