if
语句?if __name__ == "__main__":
print("Hello, World!")
如果您要关闭一个问题,而有人应该使用这个习惯用语却没有使用,请考虑将其作为为什么在导入时Python运行我的模块,我该如何停止?的重复项进行关闭。对于那些只是没有调用任何函数或错误地期望使用名为main
的函数作为自动入口点的问题,请使用当我启动Python脚本时,为什么不运行main()函数?脚本从哪里开始运行?。
if
语句?if __name__ == "__main__":
print("Hello, World!")
如果您要关闭一个问题,而有人应该使用这个习惯用语却没有使用,请考虑将其作为为什么在导入时Python运行我的模块,我该如何停止?的重复项进行关闭。对于那些只是没有调用任何函数或错误地期望使用名为main
的函数作为自动入口点的问题,请使用当我启动Python脚本时,为什么不运行main()函数?脚本从哪里开始运行?。
其他回答这个问题的内容都太长了。实际上,机制非常简单,只有两个基本事实:
纯Python模块始终使用变量__name__
设置为字符串"__main__"
。
导入模块会改变__name__
变量的值为去除.py
扩展名的基本文件名。
人们编写__name__ == '__main__'
来测试模块是否已被导入。
通常会有一些代码在导入时不应运行:测试代码、一次性使用的代码、命令行前端或Web服务器前端。
想法是直接运行模块的人希望发生这些操作,但导入模块的人只想要直接访问函数、类和变量。
从其他答案中可以看出,人们似乎能够无限地谈论这个主题,但它真的很简单,很容易掌握。Python教程 在阅读约两分钟的时间内涵盖了这个主题。不要让其他回答让你感到过度解释 :-)
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
Python 中的每个模块都有一个特殊的属性称为 __name__
。当模块作为主程序执行时(例如运行 python foo.py
),__name__
属性的值将设置为 '__main__'
。
否则,__name__
的值将设置为它所调用的模块的名称。
当执行Python文件时,它会创建许多特殊变量,例如__name__
。变量__name__
保存的是文件的名称。而你的问题的答案就是:
if __name__ == "__main__":
# Do something
这意味着,如果执行的文件名称是源文件而不是模块,则会运行其中的代码。可以用一个简单的例子来证明这一点。创建两个Python文件:foo.py
和second.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!
__name__
:if __name__ == "__main__":
print("file1 is being run directly")
else:
print("file1 is being imported")
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
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
if __name__ == "__main__"
语句允许你将Python文件既作为可重用模块也可以作为独立的程序运行。__name__
设置为一个值"__main__"
。if
语句,用于检查__name__
是否等于__main__
。__name__ == '__main__'
当我们import
一个模块时,其中所有的代码都会从头到尾执行。但是当它到达条件时,它不会运行func、func2等,也就是维基百科的__scrape__
。__name__
变量为当前程序的'__main__'
。import
一个模块时,它会被定义为当前程序名称空间中的一个变量,而当前程序的__name__
是'__main__'
:
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'>
除了已经提供的信息外,if __name__ == "__main__":
技术也是一种很好的方式,可以确保您的 pytest
和 unittest
脚本在意外使用 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
相同的效果,等等。这是一种非常好的方式,可以确保脚本仍然按预期运行,即使没有使用预期的pytest
或python -m unittest
调用。__name__
。
运行这个Python文件__name__
打印语句。print(__name__)
仍将执行。__main__
。但在第二种情况下,输出将不同(根据Python文件的名称)。if __name__ == "__main__"
,它将返回True,如果Python文件作为独立脚本运行而不是导入。但如果被导入,这将评估为False。你为什么需要所有这些?if __name__ == '__main__'
,那么我们就可以直接运行脚本。如果脚本中没有包含 if __name__ == '__main__'
(或其他名称),则无法直接运行该脚本。
if __name__
检查保护的代码仅在作为命令调用时运行,而不是在导入时运行。 如果您想使用交互式Python会话调试Python脚本,这也很有用。 您可以在交互式会话中“导入”通常作为命令运行的代码,然后手动输入代码以您喜欢的方式运行脚本中的函数/类。 - cnamejj