这样做做什么,为什么应该包括:if语句?

if __name__ == "__main__":
    print("Hello, World!")

如果你试图结束一个问题 如果你想要结束一个问题 在那里有人应该应该 使用这个学说,而不是,是不是, 考虑关闭作为 重复的为什么Python在我进口时 运行我的模块? 我该如何阻止它?。而对于某些问题,如果有人只是没有调用任何函数,或者错误地期望指定函数main自动用作切入点,使用当我启动 Python 脚本时, 主函数为何不运行? 脚本从哪里开始运行 ?.


当前回答

让我们更抽象地看待答案:

假设我们有这个密码x.py:

...
<Block A>
if __name__ == '__main__':
    <Block B>
...

区块 A 和 B 正在运行时运行x.py.

但是,在我们运行另一个模块时,只运行A区块(而不是B区块),y.py例如,x.py导入并运行代码(例如当函数在x.py调自y.py).

其他回答

"如果"允许您选择使用 python 文件作为模块或脚本

  1. 如果(如果)名称名称名称名称名称=='主要`然后 python 文件被用作脚本 - 在这个语句下有逻辑值 。
  2. 如果名称名称名称名称名称 != '主要只有此 python 文件的函数/变量可用于其他 python 脚本enter image description here

当您在本地交互运行 Python 时__name__变量的变量被指定值__main__同样,当您从命令行执行 Python 模块时,而不是将它导入到另一个模块中时,它__name__属性的属性被指定值__main__,而不是模块的实际名称。这样,模块可以查看自己的__name__用于确定它们是如何使用的值, 无论是作为对其它程序的支持还是作为从命令行执行的主要应用程序。 因此, 在 Python 模块中, 下列语系非常常见 :

if __name__ == '__main__':
    # Do something appropriate here, like calling a
    # main() function defined elsewhere in this module.
    main()
else:
    # Do nothing. This module has been imported by another
    # module that wants to make use of the functions,
    # classes and other useful bits it has defined.

短答

保护用户在无意时不意外地引用剧本的锅炉牌代码。 当剧本遗漏了警卫时, 这里有一些常见的问题:

  • 如果您在另一个脚本中导入了无保护脚本(例如 ) 。import my_script_without_a_name_eq_main_guard))),后一脚本将触发前一脚本运行导入时使用第二脚本命令行参数。这几乎总是一个错误。

  • 如果您在无警卫的脚本中有自定义类, 并将其保存为泡菜文件, 那么在另一部脚本中拆开它就会触发无警卫的脚本的输入, 与前一颗子弹中描述的相同问题 。

长答答

为了更好地了解为什么和如何看待这一问题,我们需要退一步,了解Python初始化脚本的方式,以及这如何与其模块输入机制相互作用。

Python 译员读到源文件时,

  • 它设置了几个特殊的变量,比如__name__,然后

  • 它执行文件中发现的所有代码。

让我们看看这是怎么回事 和它与你的问题有什么关系__name__我们总是在 Python 脚本中看到检查。

代码样本

让我们使用略微不同的代码样本来探索导入和脚本是如何工作的。 假设以下是在一个名为foo.py.

# Suppose this is foo.py.

print("before import")
import math

print("before function_a")
def function_a():
    print("Function A")

print("before function_b")
def function_b():
    print("Function B {}".format(math.sqrt(100)))

print("before __name__ guard")
if __name__ == '__main__':
    function_a()
    function_b()
print("after __name__ guard")

特殊变量

当 Python 口译员读取源文件时, 它首先定义了几个特殊变量。 在这种情况下, 我们关心的是__name__变量。

当您的模块是主程序时

如果您正在将模块(源文件)作为主程序运行,例如 。

python foo.py

口译员将指定硬编码字符串"__main__"会 议 日 和 排__name__变量,即:

# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__name__ = "__main__" 

当您的模块被另一个模块导入时

另一方面,假设某个其他模块是主程序, 它会导入您的模块。 这意味着在主程序或其它模块中, 有类似这样的语句, 或者是主要程序导入 :

# Suppose this is in some other main program.
import foo

译员会搜索您foo.py文件( 加上搜索其它几个变量) 执行该模块之前, 它会指定名称"foo"从导入对帐单到__name__变量,即:

# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"

执行模块代码

设置特殊变量后, 口译员将执行模块中的所有代码, 一次执行一个语句。 您可能想要用代码样本在侧面打开另一个窗口, 以便您可以随此解释一起执行 。

总是

  1. 它印着弦"before import"(没有引文)。

  2. 里面装满了math模块,然后将它指派给一个变量,该变量被称为math。这等于替换import math(注:__import__是在 Python 中的低级别函数, 需要字符串并触发实际导入 :

# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
  1. 它印着弦"before function_a".

  2. 它执行def键,创建函数对象,然后将该函数对象指定给一个被称作变量的变量function_a.

  3. 它印着弦"before function_b".

  4. 它执行第二个def键,创建另一个函数对象,然后将其指派到一个被调用的变量function_b.

  5. 它印着弦"before __name__ guard".

只有当您的模块是主程序时

  1. 如果您的模块是主程序, 它就会看到__name__确实设定"__main__"它调用两个功能, 打印字符串"Function A""Function B 10.0".

只有当您的模块被另一个模块导入时

  1. (取代如果您的模块不是主程序,而是被另一个程序导入,那么__name__"foo",而不是"__main__"它会跳过if语句。

总是

  1. 它会打印字符串"after __name__ guard"这两种情况都存在。

摘要摘要摘要

简而言之,这里是两个案例的印刷品:

# What gets printed if foo is the main program
before import
before function_a
before function_b
before __name__ guard
Function A
Function B 10.0
after __name__ guard
# What gets printed if foo is imported as a regular module
before import
before function_a
before function_b
before __name__ guard
after __name__ guard

为什么它这样工作?

你可能会自然而自然而自然地想知道为什么有人想要这个。.py可用于其他程序和/或模块作为模块的文件,也可以作为主要程序本身运行。例如:

  • 您的模块是一个库, 但是您想要有一个脚本模式, 它运行一些单元测试或演示 。

  • 您的模块仅作为主程序使用, 但它有一些单位测试, 以及导入的测试框架 。.py比如您的脚本文件, 并运行特殊测试功能。 您不希望它仅仅因为正在导入模块而尝试运行脚本 。

  • 您的模块大多用作主要程序, 但也为高级用户提供程序员友好的 API 。

除了这些例子之外, 在 Python 中运行脚本只是设置一些神奇变量, 并导入脚本, 这是优雅的。 “ 运行” 脚本是导入脚本模块的副作用 。

" 思想食品 " 组织

  • 问题:我能有多个__name__检查路障?回答:这样做很奇怪, 但语言不会阻止你。

  • 假设以下是foo2.py。如果你说,会发生什么呢?python foo2.py指挥线上?

# Suppose this is foo2.py.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters

def function_a():
    print("a1")
    from foo2 import function_b
    print("a2")
    function_b()
    print("a3")

def function_b():
    print("b")

print("t1")
if __name__ == "__main__":
    print("m1")
    function_a()
    print("m2")
print("t2")
      
  • 现在,找出如果你删除__name__检查中foo3.py:
# Suppose this is foo3.py.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters

def function_a():
    print("a1")
    from foo3 import function_b
    print("a2")
    function_b()
    print("a3")

def function_b():
    print("b")

print("t1")
print("m1")
function_a()
print("m2")
print("t2")
  • 当作为脚本使用时, 这将做什么 ? 当作为模块导入时 ?
# Suppose this is in foo4.py
__name__ = "__main__"

def bar():
    print("bar")
    
print("before __name__ guard")
if __name__ == "__main__":
    bar()
print("after __name__ guard")

if __name__ == "__main__"是在脚本从命令行运行时运行的部分,使用类似命令python myscript.py.

简而言之,你需要知道几点:

  1. import a动作实际上运行所有可以运行的a.py,意指每一行a.py

  2. 因为第1点,你可能不希望一切 运行在a.py进口时

  3. 要解决第2点的问题, Python 允许您使用条件检查

  4. __name__全部为隐含变量.py模块 :

  • 何时a.pyimported, 数值__name__联 联 年 月 日 月 日 月 月 日 月 月 日 月 月 月 日 月 月 日 月 月 日 月 月 月 日 月 月 日 月 月 月 日 月 的 月 月 月 日 月 月 日 月 的 月 月 月 月 日 月 月 月a.py模块设置为文件名 "a"
  • 何时a.py直接使用“python a.py" , " 价值__name__设置为字符串__main__
  1. 基于 Python 如何设置变量的机制__name__每个模块的每个模块, 您知道如何达到第3点吗 ? 答案相当简单, 对吧? 使用如果条件 :if __name__ == "__main__": // do A
  • 时当时python a.py将运行此部件// do A
  • import a跳过此部分// do A
  1. 你甚至可以放__name__ == "a"取决于你的功能需要,但很少

Python在4点是特别的 重要的事!

我在这页的答案中读了这么多。我想说,如果你知道这件事的话,你肯定能理解那些答案, 否则,你还是很困惑。