如果 __name__ == "__main__" 是什么意思?

8132
这段代码的作用是什么?为什么要使用 if 语句?
if __name__ == "__main__":
    print("Hello, World!")

如果您要关闭一个问题,而有人应该使用这个习惯用语却没有使用,请考虑将其作为为什么在导入时Python运行我的模块,我该如何停止?的重复项进行关闭。对于那些只是没有调用任何函数或错误地期望使用名为main的函数作为自动入口点的问题,请使用当我启动Python脚本时,为什么不运行main()函数?脚本从哪里开始运行?


38
“__main__”是Python中的一个特殊变量,表示当前执行的模块是主程序。当一个Python程序被直接运行时,它的“__name__”变量被设置为“__main__”,而当它被作为一个模块导入到其他程序中时,“__name__”变量会被设置为该模块的名称。更多信息可以查看文档:https://docs.python.org/3/reference/toplevel_components.html#complete-python-programs 和 https://docs.python.org/3/reference/import.html?highlight=__name__#__name__ - Konstantin Burlachenko
30
有多少人来到这里是因为想要复制粘贴“if name == "main":”呢?:-P - Aaron John Sabu
2
如果您想编写旨在被“导入”但也可以作为独立的shell脚本运行的Python代码,这将非常有用。 由if __name__检查保护的代码仅在作为命令调用时运行,而不是在导入时运行。 如果您想使用交互式Python会话调试Python脚本,这也很有用。 您可以在交互式会话中“导入”通常作为命令运行的代码,然后手动输入代码以您喜欢的方式运行脚本中的函数/类。 - cnamejj
3
对于任何来到这里的人,[7:32] You should put this in all your Python scripts | if __name__ == '__main__': ... by YouTube channel mCoding 提供了一个很好的解释和讨论这个习语的后果。标题可能对于SO来说太过规定,但是解释很好。 - eccentricOrange
46个回答

10

你需要知道的事实

其他回答这个问题的内容都太长了。实际上,机制非常简单,只有两个基本事实:

  1. 纯Python模块始终使用变量__name__设置为字符串"__main__"

  2. 导入模块会改变__name__变量的值为去除.py扩展名的基本文件名。

如何使用这些信息

人们编写__name__ == '__main__'来测试模块是否已被导入。

通常会有一些代码在导入时不应运行:测试代码、一次性使用的代码、命令行前端或Web服务器前端。

想法是直接运行模块的人希望发生这些操作,但导入模块的人只想要直接访问函数、类和变量。

从其他答案中可以看出,人们似乎能够无限地谈论这个主题,但它真的很简单,很容易掌握。Python教程 在阅读约两分钟的时间内涵盖了这个主题。不要让其他回答让你感到过度解释 :-)


1
这应该是被接受的答案。它需要被移到顶部! - Rich Lysakowski PhD

9
创建一个文件,a.py:
print(__name__) # It will print out __main__

__name__指的是文件被直接运行时,总是等于__main__,这表明该文件是主文件。

在同一目录下创建另一个文件,名为b.py

import a  # Prints a

运行它。它将打印 a,即被导入的文件的名称。

因此,为了展示同一文件的两种不同行为,这是一个常用的技巧:

# Code to be run when imported into another python file

if __name__ == '__main__':
    # Code to be run only when run directly

9

Python 中的每个模块都有一个特殊的属性称为 __name__。当模块作为主程序执行时(例如运行 python foo.py),__name__ 属性的值将设置为 '__main__'

否则,__name__ 的值将设置为它所调用的模块的名称。


1
Re “...the name of the module that it was called from”: 不是模块本身吗?这听起来不太可能。如果确实是这种情况,您能否在您的答案中详细说明?(但是不要包括“编辑:”,“更新:”或类似内容 - 答案应该看起来像今天编写的。) - Peter Mortensen

6

当执行Python文件时,它会创建许多特殊变量,例如__name__。变量__name__保存的是文件的名称。而你的问题的答案就是:

if __name__ == "__main__":
       # Do something

这意味着,如果执行的文件名称是源文件而不是模块,则会运行其中的代码。可以用一个简单的例子来证明这一点。创建两个Python文件:foo.pysecond.py。然后在foo.py中输入以下内容:

if __name__ == "__main__":
       print("file is not imported")
else:
       print("file is imported")

second.py中,输入以下内容:

import foo

if foo.__name__ == "__main__":
       print("file is not imported")
else:
       print("file is imported")

此外,如果您执行print(__name__),它将打印__main__。为什么?
因为该文件正在作为主要源运行,如果您使用print(foo.__name__),它将打印foo,因为__name__变量的默认值是文件名,并且默认情况下,您也可以更改它。要做到这一点,只需进入foo.py文件并执行此操作:__name__ =“name”。然后当您运行文件时,例如:
__name__ = "Hello, World!"
print(__name__)

那么输出结果将是:

Hello, World!

6
你可以通过以下简单的示例来检查特殊变量__name__
创建file1.py文件。
if __name__ == "__main__":
    print("file1 is being run directly")
else:
    print("file1 is being imported")

创建*file2.py文件。
import file1 as f1

print("__name__ from file1: {}".format(f1.__name__))
print("__name__ from file2: {}".format(__name__))

if __name__ == "__main__":
    print("file2 is being run directly")
else:
    print("file2 is being imported")

执行file2.py文件

输出结果:

file1 is being imported
__name__ from file1: file1
__name__ from file2: __main__
file2 is being run directly

5

Python主函数是任何程序的起点。当程序运行时,Python解释器按顺序运行代码。只有在将其作为Python程序运行时,才会执行主函数...

def main():
    print("I am in the function")

print("I am out of the function")

当您运行脚本时,会显示:
I am out of the function

并不是代码 "I am in the function"。

这是因为我们没有声明调用函数 "if__name__== "main"。

如果你使用的话:

def main():
    print("I am in the function")

if __name__ == "__main__":
    main()

print("I am out of the function")

输出等于

I am in the function
I am out of the function

在Python中,if __name__ == "__main__"语句允许你将Python文件既作为可重用模块也可以作为独立的程序运行。
当Python解释器读取源代码文件时,它会执行其中所有的代码。当Python以主程序的方式运行"源文件"时,会将特殊变量__name__设置为一个值"__main__"
当你执行主函数时,它将会读取if语句,用于检查__name__是否等于__main__

1
我不禁觉得这更加令人困惑,而非有所帮助。 - tripleee

2
假设我编写了用于在维基百科上进行网络爬虫的函数和类。当然,这可能不是一个好的例子。
我想在另一个程序中使用这些函数而不需要重新编写它们。
那么,我会将它们导入,但在文件末尾我会加上__name__ == '__main__' 当我们import一个模块时,其中所有的代码都会从头到尾执行。但是当它到达条件时,它不会运行funcfunc2等,也就是维基百科的__scrape__
好的,在全局范围内,Python定义了一个__name__变量为当前程序的'__main__'
当我们import一个模块时,它会被定义为当前程序名称空间中的一个变量,而当前程序的__name__'__main__'

文件test.py

def func():
    # Do something
    pass

def func2():
    # Do something
    pass

print('The program name is set to ', globals()['__name__'])

if __name__=='__main__':
    # In the current program, __name__ is equal to '__main__'
    func('https://www.wikipedia.org')
    func2('https://www.wikipedia.org')
    # Or do more jobs


import test1
print('inside of current program')
print('name is current program', __name__)
print(globals()['test1'])
test1.func('another site')
test1.func2('another site')

输出

inside of test 1
name of program is set to test1
end of module
inside of current
__main__
<module 'test1' from 'C:\\users\\ir\\appdata\\local\\programs\\python\\python38\\lib\\test1.py'>

列出的输出与列出的代码相比非常不同步。你不能复制粘贴它,而不是引入打字错误吗?请在此处编辑:https://stackoverflow.com/posts/68244934/edit - Peter Mortensen
1
你在这里写作不需要获得许可,但是为了你自己和读者的利益,请使用大写字母并且不要省略标点符号。这并不需要任何技能,只需要改变习惯的意愿。而且不要省略冠词 - 这需要一些技能,但真的那么难吗?如果你不这样做,你会从一开始就处于劣势。改变这种习惯也将极大地增强你在就业市场上的机会。提前致谢。 - Peter Mortensen

1

除了已经提供的信息外,if __name__ == "__main__": 技术也是一种很好的方式,可以确保您的 pytestunittest 脚本在意外使用 python 调用时仍然能够运行(或者使用 python -m unittest)。以下是一个示例:

def test_assert():
    assert 1 + 2 == 3

if __name__ == "__main__":
    import pytest
    pytest.main([__file__])

现在,您的测试将无论使用 pytest 还是 python 调用都可以运行。这是 unittest 版本:

import unittest

class Tests(unittest.TestCase):
    def test_assert(self):
        self.assertTrue(1 + 2 == 3)

if __name__ == "__main__":
    unittest.main()

使用python调用脚本和使用python -m unittest调用脚本的效果相同。

现在,如果您想确保所有参数在使用python调用时都被传递给pytest,或者如果您还想包含其他参数,可以按照以下示例操作:

def test_assert():
    assert 1 + 2 == 3

if __name__ == "__main__":
    from pytest import main
    from sys import argv
    main([*argv, "-s"])

现在,您的python -v --html=report.html将产生与pytest -v --html=report.html相同的效果,等等。这是一种非常好的方式,可以确保脚本仍然按预期运行,即使没有使用预期的pytestpython -m unittest调用。

1
在你的项目中执行以下操作。
创建一个Python文件,简单地打印__name__。 运行这个Python文件
现在,在另一个Python文件中导入此Python文件。不要触摸__name__打印语句。
导入后,print(__name__)仍将执行。
首先,输出将是__main__。但在第二种情况下,输出将不同(根据Python文件的名称)。
因此,如果添加一个if检查if __name__ == "__main__",它将返回True,如果Python文件作为独立脚本运行而不是导入。但如果被导入,这将评估为False。你为什么需要所有这些?
也许你的Python文件是基于类或函数的。你可能想在不同的Python文件中重用这些类或函数。但是,当该Python脚本作为独立脚本执行时,您可能不想执行要执行的Python脚本。
因此,请确保几乎每个Python文件都添加这个。

0
如果代码中包含 if __name__ == '__main__',那么我们就可以直接运行脚本。如果脚本中没有包含 if __name__ == '__main__'(或其他名称),则无法直接运行该脚本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接