提问



if __name__ == "__main__":做了什么?


# Threading example
import time, thread

def myfunction(string, sleeptime, lock, *args):
    while True:
        lock.acquire()
        time.sleep(sleeptime)
        lock.release()
        time.sleep(sleeptime)

if __name__ == "__main__":
    lock = thread.allocate_lock()
    thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
    thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

最佳参考


当Python解释器读取源文件时,它会执行其中的所有代码。


在执行代码之前,它将定义一些特殊变量。例如,如果Python解释器将该模块(源文件)作为主程序运行,则它将特殊__name__变量设置为具有值"__main__"。如果从另一个模块导入此文件,__name__将被设置为模块的名称。


在你的脚本的情况下,让我们假设它作为主要功能执行,例如你说的话


python threading_example.py


在命令行上。设置特殊变量后,它将执行import语句并加载这些模块。然后它将评估def块,创建一个函数对象并创建一个名为myfunction的变量,该变量指向函数对象。然后它将读取if语句并看到__name__确实等于"__main__",因此它将执行那里显示的块。


这样做的一个原因是有时你会编写一个模块(.py文件),它可以直接执行。或者,它也可以导入并在另一个模块中使用。通过执行主检查,您可以仅在希望将模块作为程序运行时执行该代码,而在有人只想导入模块并自行调用函数时不执行该代码。


有关其他详细信息,请参阅此页。[230]

其它参考1


通过将脚本作为命令传递给Python解释器来运行脚本时,


python myscript.py


处于缩进级别0的所有代码都将被执行。已定义的函数和类已定义,但它们的代码都不会运行。与其他语言不同,没有main()函数可以自动运行 - main()函数隐含了顶层的所有代码。


在这种情况下,顶级代码是if块。 __name__是一个内置变量,它计算当前模块的名称。但是,如果直接运行模块(如上面myscript.py中所述),则__name__将设置为字符串"__main__"。因此,您可以通过测试来测试脚本是直接运行还是由其他内容导入


if __name__ == "__main__":
    ...


如果你的脚本被导入到另一个模块中,它的各种函数和类定义将被导入并且它的顶层代码将被执行,但是上面if子句的then-body中的代码不会被获取在不满足条件的情况下运行。作为一个基本示例,请考虑以下两个脚本:


# file one.py
def func():
    print("func() in one.py")

print("top-level in one.py")

if __name__ == "__main__":
    print("one.py is being run directly")
else:
    print("one.py is being imported into another module")




# file two.py
import one

print("top-level in two.py")
one.func()

if __name__ == "__main__":
    print("two.py is being run directly")
else:
    print("two.py is being imported into another module")


现在,如果你调用解释器


python one.py


输出将是


top-level in one.py
one.py is being run directly


如果你改为运行two.py:


python two.py


你得到


top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly


因此,当模块one被加载时,其__name__等于"one"而不是"__main__"

其它参考2


__name__变量(imho)的最简单解释如下:


创建以下文件。


# a.py
import b





# b.py
print "Hello World from %s!" % __name__

if __name__ == '__main__':
    print "Hello World again from %s!" % __name__


运行它们会得到这个输出:


$ python a.py
Hello World from b!


如您所见,在导入模块时,Python将此模块中的globals()['__name__']设置为模块的名称。


$ python b.py
Hello World from __main__!
Hello World again from __main__!


如您所见,当执行文件时,Python将此文件中的globals()['__name__']设置为"__main__"

其它参考3



  

if __name__ == "__main__":做什么?




概述基础知识:



  • 作为程序入口点的模块中的全局变量__name__'__main__'。否则,它是您导入模块的名称。

  • 因此,只有当模块是程序的入口点时,if块下的代码才会运行。

  • 它允许模块中的代码可由其他模块导入,而无需在导入时执行下面的代码块。






我们为什么需要这个?


开发和测试您的代码



假设你正在编写一个旨在用作模块的Python脚本:


def do_important():
    """This function does something very important"""


您可以通过将此函数调用添加到底部来 测试模块:


do_important()


并运行它(在命令提示符下),例如:


~$ python important.py


问题



但是,如果要将模块导入另一个脚本:


import important


在导入时,将调用do_important函数,因此您可能会在底部注释掉函数调用do_important()


# do_important() # I must remember to uncomment to execute this!


然后你必须记住你是否已经注释掉你的测试函数调用。而这种额外的复杂性意味着你可能会忘记,让你的开发过程更加麻烦。


更好的方式



__name__变量指向Python解释器恰好在哪里的命名空间。


在导入的模块中,它是该模块的名称。


但是在主模块(或交互式Python会话,即解释器的Read,Eval,Print Loop或REPL)中,您运行的是"__main__"中的所有内容。


所以如果你在执行前检查:


if __name__ == "__main__":
    do_important()


通过上述操作,您的代码将仅在您将其作为主模块运行时(或故意从其他脚本调用它)时执行。


更好的方式



不过,有一种Pythonic方法可以改进这一点。


如果我们想从模块外部运行此业务流程怎么办?


如果我们在我们开发和测试这样的函数时放置我们想要运用的代码,然后立即检查'__main__':


def main():
    """business logic for when running this module as the primary one!"""
    setup()
    foo = do_important()
    bar = do_even_more_important(foo)
    for baz in bar:
        do_super_important(baz)
    teardown()

# Here's our payoff idiom!
if __name__ == '__main__':
    main()


我们现在有一个最终函数用于模块的结束,如果我们将模块作为主模块运行,它将运行。


它将允许将模块及其函数和类导入到其他脚本中而无需运行main函数,并且还允许在从不同的'__main__'运行时调用模块(及其函数和类)。]]模块,即


import important
important.main()


这个习惯用法也可以在Python文档的__main__模块的解释中找到。该案文指出:[231]



  此模块表示(否则为匿名)范围
  解释器的主程序执行 - 从中​​读取命令
  标准输入,脚本文件或交互式提示。它
  是这个环境中的惯用语条件脚本节
  导致脚本运行:


if __name__ == '__main__':
    main()


其它参考4


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

其它参考5



  

if __name__ == "__main__":做什么?




__name__是一个全局变量(在Python中,全局实际上意味着在模块级别上),它存在于所有名称空间中。它通常是模块的名称(作为str类型)。[232]


然而,作为唯一的特殊情况,无论你在哪个Python进程中运行,如在mycode.py中:


python mycode.py


否则匿名全局命名空间被赋予'__main__'的值到其__name__


因此,包括最后一行[233]


if __name__ == '__main__':
    main()



  • 在mycode.py脚本的末尾,

  • 当它是由Python进程运行的主要入口点模块时,



将导致脚本的唯一定义main函数运行。


使用此构造的另一个好处是:您还可以将代码作为模块导入另一个脚本中,然后在程序决定时运行main函数:


import mycode
# ... any amount of other code
mycode.main()

其它参考6


这里有很多不同的关于代码的机制,如何,但对我来说,除非我理解为什么,否则它们都没有意义。这应该对新程序员特别有用。


取文件ab.py:


def a():
    print('A function in ab file');
a()


第二个文件xy.py:


import ab
def main():
    print('main function: this is where the action is')
def x():
    print ('peripheral task: might be useful in other projects')
x()
if __name__ == "__main__":
    main()



  这段代码到底在做什么?



执行xy.py时,import ab。 import语句在导入时立即运行模块,因此ab的操作在xy的剩余部分之前执行。完成ab后,继续xy


解释器使用__name__跟踪正在运行的脚本。当您运行脚本时 - 无论您将其命名为什么 - 解释器都会调用它"__main__",使其成为运行外部脚本后返回的主或主脚本。


"__main__"脚本调用的任何其他脚本的文件名都被指定为__name__(例如,__name__ == "ab.py")。因此,行if __name__ == "__main__":是解释器s测试以确定它是否解释/解析最初执行的主脚本,或者它是否暂时窥视另一个(外部)脚本。这使程序员可以灵活地使脚本的行为不同,如果它直接执行而不是外部调用。


让我们逐步完成上面的代码,了解发生了什么,首先关注的是未缩进的行以及它们在脚本中出现的顺序。请记住,功能 - 或def - 阻止他们自己做任何事情,直到他们被召唤。如果嘟to自己,翻译可能会说些什么:



  • 打开xy.py作为主页文件;在__name__变量中将其称为"__main__"

  • 使用__name__ == "ab.py"导入并打开文件。

  • 哦,一个功能。我会记得的。

  • 好的,功能a();我刚学会了这个。打印 ab文件中的功能。

  • 文件结束;回到"__main__"!

  • 哦,一个功能。我会记得的。

  • 另一个。

  • 功能x();好的,打印外围任务:可能在其他项目中很有用。

  • 这是什么?if声明。嗯,条件已经满足(变量__name__已设置为"__main__"),所以我将进入main()功能和打印主要功能:这是动作。



底部两行表示:如果这是"__main__"或home脚本,则执行名为main()的函数。这就是为什么你会看到一个def main():块顶部,其中包含脚本功能的主要流程。



  为什么实现这个?



还记得我之前说的关于import语句的内容吗?导入模块时,它不会识别它并等待进一步的指令 - 它实际上运行了脚本中包含的所有可执行操作。因此,将脚本的内容放入main()函数中有效隔离它,将它隔离,以便在被另一个脚本导入时立即运行。


同样,会有例外,但通常的做法是main()通常不会被外部调用。所以你可能想知道另一件事:如果我们不打电话main(),我们为什么要打电话脚本在哪?这是因为许多人使用独立函数构建脚本,这些函数构建为独立于文件中其余代码运行。然后它们会在脚本体中的其他位置调用。这让我想到了这个:



  但代码在没有它的情况下工作



是的,那是对的。这些单独的函数可以从一个不包含在main()函数中的内联脚本调用。如果您已经习惯(就像我在编程的早期学习阶段一样)来构建完全符合您需要的内联脚本,并且如果您再次需要该操作,那么您将尝试再次弄清楚它。好吧,你不习惯你的代码的这种内部结构,因为它构建起来更复杂,而且阅读不那么直观。


但这是一个可能无法在外部调用其函数的脚本,因为如果这样做,它会立即开始计算和分配变量。如果您正在尝试重新使用某个函数,那么您的新脚本可能与旧版本密切相关,因为存在冲突的变量。


在拆分独立函数时,您可以通过将它们调用到另一个脚本中来重用以前的工作。例如,example.py可能导入xy.py并调用x(),利用xy.py中的x函数。 (也许它正在大写给定文本字符串的第三个单词;从数字列表中创建NumPy数组并将它们平方;或者去除3D表面的去除。可能性是无限的。)


(顺便说一句,这个问题包含@kindall的答案,最终帮助我理解 - 为什么,而不是如何。不幸的是,它被标记为这个的副本,我认为这是一个错误。)

其它参考7


当我们的模块中存在某些语句(M.py)时,我们希望在它将作为主要(未导入)运行时执行,我们可以将这些语句(测试用例,打印语句)置于此[[M.py之下if阻止。


默认情况下(当模块作为main运行,而不是导入时)__name__变量设置为"__main__",当它将被导入时,__name__变量将获得不同的值,大多数可能是模块的名称('M')。
这有助于将模块的不同变体一起运行,并将它们的特定输入和输出分开。输出语句以及是否有任何测试用例。


简而言之,使用此if __name__ == "main"块可防止在导入模块时运行(某些)代码。

其它参考8


让我们以更抽象的方式看待答案:


假设我们在x.py中有这个代码:


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


当我们运行x.py时,块A和B运行。


但是当我们运行另一个模块时,只运行块A(而不是B),例如y.py,其中导入了xy并且从那里运行代码(就像x.py中的函数是从y.py调用。

其它参考9


以交互方式运行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.

其它参考10


简而言之,__name__是为每个脚本定义的变量,用于定义脚本是作为主模块运行还是作为导入模块运行。


所以,如果我们有两个脚本;


#script1.py
print "Script 1's name: {}".format(__name__)





#script2.py
import script1
print "Script 2's name: {}".format(__name__)


执行script1的输出是


Script 1's name: __main__


执行script2的输出是:


Script1's name is script1
Script 2's name: __main__


如您所见,__name__告诉我们哪个代码是主模块。
这很好,因为你可以只编写代码而不必担心C/C ++中的结构问题,如果文件没有实现main函数那么它就不能编译为可执行文件,如果是的话,它不能用作库。


假设您编写了一个Python脚本,它可以执行一些非常棒的操作,并且可以实现一系列对其他用途有用的函数。如果我想使用它们,我只需导入你的脚本并使用它们而不执行你的程序(假设你的代码只在if __name__ == "__main__":上下文中执行)。而在C/C ++中,您必须将这些部分分成一个单独的模块,然后包含该文件。想象下面的情况;


[236]


箭头是导入链接。对于每个试图包含前面的模块代码的三个模块,有六个文件(九个,计算实现文件)和五个链接。这使得很难将其他代码包含到C项目中,除非它专门编译为库。现在想象一下Python:


[237]


你编写了一个模块,如果有人想使用你的代码,他们只需导入它,__name__变量可以帮助将程序的可执行部分与库部分分开。

其它参考11


考虑:


if __name__ == "__main__":
    main()


它检查Python脚本的__name__属性是否为"__main__"。换句话说,如果程序本身被执行,属性将是__main__,因此程序将被执行(在这种情况下是main()函数)。


但是,如果您的Python脚本由模块使用,则if语句之外的任何代码都将被执行,因此if \__name__ == "\__main__"仅用于检查程序是否用作模块,并且因此决定是否运行代码。

其它参考12


从命令行调用Python文件时,这是一个特殊的功能。这通常用于调用main()函数或执行其他适当的启动代码,例如命令行参数处理。


它可以用几种方式编写。另一个是:


def main():
    dosomething()


__name__ == '__main__' and main()


我并不是说你应该在生产代码中使用它,但它可以说明if __name__ == '__main__'没有什么神奇。它是一个(伟大的!)约定,用于在Python文件中调用main函数。

其它参考13


系统(Python解释器)为源文件(模块)提供了许多变量。您可以随时获取其值,因此,让我们关注 __ name __ 变量/属性:


当Python加载源代码文件时,它会执行其中的所有代码。 (请注意,它不会调用文件中定义的所有方法和函数,但它确实定义了它们。)


在解释器执行源代码文件之前,它为该文件定义了一些特殊变量; __ name __ 是Python为每个源代码文件自动定义的特殊变量之一。


如果Python将此源代码文件作为主程序(即您运行的文件)加载,则它会为此文件设置特殊的 __ name __ 变量,使其具有值__ main __


如果从其他模块导入,则 __ name __ 将设置为该模块的名称。


所以,在你的例子中:


if __name__ == "__main__":
   lock = thread.allocate_lock()
   thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
   thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))


意味着代码块:


lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))


只有在你直接运行模块时才会执行;如果另一个模块正在调用/导入它,则代码块将不会执行,因为 __ name __ 的值在该特定实例中不等于 main


希望这会有所帮助。

其它参考14


我认为最好用深入简单的方式打破答案:


__name__:Python中的每个模块都有一个名为__name__的特殊属性。
它是一个内置变量,它返回模块的名称。


__main__:与其他编程语言一样,Python也有一个执行入口点,即main。 '__main__' 是顶级代码执行的范围的名称。基本上,您有两种使用Python模块的方法:直接将其作为脚本运行,或者导入它。当模块作为脚本运行时,其__name__设置为__main__


因此,当模块作为主程序运行时,__name__属性的值设置为__main__。否则,__name__的值设置为包含模块的名称。

其它参考15


if __name__ == "__main__":基本上是顶级脚本环境,它指定了解释器(我首先执行的优先级最高)。


'__main__'是顶级代码执行的范围的名称。从标准输入,脚本或交互式提示中读取时,模块的__name__设置为'__main__'


if __name__ == "__main__":
    # Execute only if run as a script
    main()

其它参考16


在解释if __name__ == '__main__'的任何内容之前,了解__name__是什么以及它的作用非常重要。



  什么是__name__?



__name__是DunderAlias - 可以被认为是一个全局变量(可从模块访问),并以与global类似的方式工作。[238]


它是一个字符串(全局如上所述),如type(__name__)所示(产生<class 'str'>),是Python 3和Python 2版本的内置标准。[240] [241]]]



  的其中:



它不仅可以在脚本中使用,还可以在解释器和模块/包中找到。


解释


>>> print(__name__)
__main__
>>>


脚本:


test_file.py :


print(__name__)


导致__main__


模块或包装:


somefile.py:


def somefunction():
    print(__name__)


test_file.py:


import somefile
somefile.somefunction()


导致somefile


请注意,在包或模块中使用时,__name__将获取文件的名称。路径of没有给出实际的模块或包路径,但有自己的DunderAlias __file__,允许这样做。


您应该看到,__name__,主文件(或程序)将始终返回__main__​​]],如果它是模块/包,或任何正在运行一些其他Python脚本,将返回它所源自的文件的名称。



  的实践:



作为变量意味着它的值可以被覆盖(可以并不意味着应该),覆盖__name__的值将导致缺乏可读性。所以不要因为任何原因这样做。如果你需要一个变量来定义一个新的变量。


始终假设__name__的值为__main__或文件的名称。再次更改此默认值将导致更多的混淆,它将做好,导致进一步的问题。


例如:


>>> __name__ = 'Horrify' # Change default from __main__
>>> if __name__ == 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>


一般认为将if __name__ == '__main__'包含在脚本中是一种好习惯。



  现在回答if __name__ == '__main__':



现在我们知道__name__事情的行为变得更加清晰:


if是一个流控制语句,如果给定的值为true,则包含将执行的代码块。我们已经看到__name__也可以采取
__main__或从中导入的文件名。 [242]


这意味着如果__name__等于__main__,则文件必须是主文件,并且必须实际运行(或者它是解释器),而不是导入到脚本中的模块或包。


如果确实__name__确实取__main__的值,那么该代码块中的任何内容都将执行。


这告诉我们如果运行的文件是主文件(或者您直接从解释器运行),那么必须执行该条件。如果它是一个包,那么它不应该,并且该值不会是__main__



  的模块:



__name__也可以在模块中用于定义模块的名称



  的变体



也可以用__name__做其他不太常见但有用的事情,我将在这里展示一些:


仅在文件是模块或包时执行:


if __name__ != '__main__':
    # Do some useful things 


如果文件是主文件,则运行一个条件,如果文件不是,则运行另一个条件:


if __name__ == '__main__':
    # Execute something
else:
    # Do some useful things


您还可以使用它在包和模块上提供可运行的帮助功能/实用程序,而无需精心使用库。


它还允许模块作为主脚本从命令行运行,这也非常有用。

其它参考17


原因


if __name__ == "__main__":
    main()


主要是为了避免因直接导入代码而导致的导入锁定问题。如果您的文件被直接调用(__name__ == "__main__"的情况),您希望main()运行,但如果您的代码已导入,则导入器必须从真正的主模块输入您的代码以避免导入锁定问题。[243]


副作用是您自动登录支持多个入口点的方法。您可以使用main()作为入口点来运行程序,但是您不必。当setup.py期望main()时,其他工具使用备用入口点例如,要将文件作为gunicorn进程运行,可以定义app()函数而不是main()。就像setup.pygunicorn导入一样你的代码所以你不希望它在导入时做任何事情(因为导入锁定问题)。

其它参考18



  您可以将文件用作脚本以及可导入模块



fibo.py(名为fibo的模块)


# Other modules can IMPORT this MODULE to use the function fib
def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

# This allows the file to be used as a SCRIPT
if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))


参考:https://docs.python.org/3.5/tutorial/modules.html [245]

其它参考19


考虑:


print __name__


上面的输出是__main__


if __name == "__main__":
  print "direct method"


以上陈述为真,并打印直接方法。假设他们在其他类中导入了这个类,它不会打印直接方法,因为在导入时,它会设置__name__ equal to "firstmodel name"

其它参考20


创建一个 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

其它参考21


所有答案都解释了功能。但我将提供一个使用它的例子,这可能有助于进一步清除这个概念。


假设您有两个Python文件,a.py和b.py.现在,a.py导入b.py.我们运行a.py文件,首先执行import b.py代码。在运行其余的a.py代码之前,文件b.py中的代码必须完全运行。


在b.py代码中,有一些代码专用于该文件b.py,我们不希望任何导入b.py文件的其他文件(b.py文件除外)运行它。


这就是这行代码检查的内容。如果它是运行代码的主文件(即b.py),在这种情况下它不是(a.py是运行的主文件),那么只有代码被执行。

其它参考22


如果名称 ==主要:



我们经常看__name__ == '__main__':


它检查是否正在导入模块。


换句话说,if块中的代码只有在代码直接运行时才会执行。这里directly表示not imported


让我们看看它使用一个打印模块名称的简单代码做了什么:


# test.py
def test():
   print('test module name=%s' %(__name__))

if __name__ == '__main__':
   print('call test()')
   test()


如果我们直接通过python test.py运行代码,模块名称为__main__:


call test()
test module name=__main__

其它参考23


如果此.py文件由其他.py文件导入,则不会执行if语句下的代码。


如果此.py由shell下的python this_py.py运行,或者在Windows中双击。 if语句下的代码将被执行。


它通常是为测试而编写的。

其它参考24


我在这个页面的答案中一直都在阅读。我会说,如果你知道这件事,你肯定会明白这些答案,否则,你仍然感到困惑。


简而言之,您需要了解以下几点:



  1. import a动作实际运行所有可以在a中运行的动作

  2. 由于第1点,您可能不希望在导入时以a运行所有内容

  3. 要解决第2点中的问题,python允许您进行条件检查

  4. __name__是所有.py模块中的隐式变量;导入a.py时,a.py模块的__name__值设置为文件名a;当a.py直接使用python a.py运行时,这意味着a.py是入口点,那么a.py模块的__name__值设置为字符串__main__

  5. 基于python为每个模块设置变量__name__的机制,你知道如何实现第3点吗?答案很简单,对吧?设if条件:if __name__ == "__main__": ...;你甚至可以根据你的功能需要放__name__ == "a"



python特别重要的是第4点!其余的只是基本逻辑。

其它参考25


_ name _ == _ main _将确保此块中存在的代码/语句仅在我们直接执行此文件时运行,而不是如果我们将其导入为在另一个python文件中的模块然后我们可以调用它中定义的函数以及_ 名称 == main _中存在的块不会被执行。