如果__name__ ==“__ main__”:怎么办?

时间:2009-01-07 04:11:00

标签: python namespaces main python-module idioms

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))

38 个答案:

答案 0 :(得分:5384)

每当Python解释器读取源文件时,它都会做两件事:

  • 它设置了一些特殊变量,如__name__,然后是

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

让我们看看它是如何工作的,以及它与您在Python脚本中总是看到的__name__检查的问题之间的关系。

代码示例

让我们使用略有不同的代码示例来探索导入和脚本的工作方式。假设以下内容位于名为foo.py的文件中。

# Suppose this is foo.py.

print("before import")
import math

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

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

print("before __name__ guard")
if __name__ == '__main__':
    functionA()
    functionB()
print("after __name__ guard")

特殊变量

当Python interpeter读取源文件时,它首先定义一些特殊变量。在这种情况下,我们关心__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,剥离.py,并将该字符串分配给模块的__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中的一个低级函数,它接受一个字符串并触发实际导入):

  3. # Find and load a module given its string name, "math",
    # then assign it to a local variable called math.
    math = __import__("math")
    
    1. 打印字符串"before functionA"

    2. 执行def块,创建一个函数对象,然后将该函数对象分配给名为functionA的变量。

    3. 打印字符串"before functionB"

    4. 执行第二个def块,创建另一个函数对象,然后将其分配给名为functionB的变量。

    5. 打印字符串"before __name__ guard"

    6. 仅当您的模块是主程序时

      1. 如果您的模块是主程序,那么它会看到__name__确实设置为"__main__"并且它调用了两个函数,打印字符串"Function A"和{{1} }。
      2. 仅当您的模块被其他人导入时

        1. 相反)如果您的模块不是主程序但是由另一个模块导入,则"Function B 10.0"将是__name__,而不是"foo",并且它会跳过"__main__"声明的主体。
        2. 始终

          1. 在两种情况下都会打印字符串if
          2. <强> 摘要

            总之,这是两种情况下打印的内容:

            "after __name__ guard"
            # What gets printed if foo is the main program
            before import
            before functionA
            before functionB
            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 functionA before functionB before __name__ guard after __name__ guard 文件,它可以被其他程序和模块用作模块,可以作为主程序运行。例子:

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

            • 您的模块仅用作主程序,但它有一些单元测试,测试框架通过导入.py文件(如脚本)和运行特殊测试功能来工作。您不希望它尝试运行脚本只是因为它正在导入模块。

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

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

            思想的食物

            • 问题:我可以拥有多个.py个检查块吗?答:这样做很奇怪,但语言不会阻止你。

            • 假设以下内容位于__name__。如果在命令行中说foo2.py会怎样?为什么呢?

            python foo2.py
            • 现在,弄清楚如果您在# Suppose this is foo2.py. def functionA(): print("a1") from foo2 import functionB print("a2") functionB() print("a3") def functionB(): print("b") print("t1") if __name__ == "__main__": print("m1") functionA() print("m2") print("t2") 中删除__name__签到会发生什么:
            foo3.py
            • 用作脚本时会怎么做?当作为模块导入?
            # Suppose this is foo3.py.
            
            def functionA():
                print("a1")
                from foo3 import functionB
                print("a2")
                functionB()
                print("a3")
            
            def functionB():
                print("b")
            
            print("t1")
            print("m1")
            functionA()
            print("m2")
            print("t2")
            

答案 1 :(得分:1632)

通过将脚本作为命令传递给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 :(得分:650)

__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__']设置为模块的名称。此外,导入时,模块中的所有代码都在运行。由于if语句的计算结果为False,因此不会执行此部分。

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

如您所见,在执行文件时,Python会将此文件中的globals()['__name__']设置为"__main__"。这一次,if语句的计算结果为True并且正在运行。

答案 3 :(得分:465)

  

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()

This idiom can also be found in the Python documentation in an explanation of the __main__ module.该文字指出:

  

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

if __name__ == '__main__':
    main()

答案 4 :(得分:106)

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

答案 5 :(得分:70)

  

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

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

然而,作为唯一的特殊情况,在您运行的任何Python进程中,如在mycode.py中:

python mycode.py

将其他匿名全局命名空间的值'__main__'分配给其__name__

因此,包括the final lines

if __name__ == '__main__':
    main()
  • 在mycode.py脚本的末尾,
  • 当它是由Python进程运行的主要入口点模块时,

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

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

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

答案 6 :(得分:61)

这里有很多关于代码机制的不同内容,&#34; How&#34;,但对我来说,直到我理解&#34;为什么&#34;它才有意义。这应该对新程序员特别有用。

记录文件&#34; ab.py&#34;:

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

第二个文件&#34; xy.py&#34;:

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__":是解释者的测试,以确定它是否解释/解析“家庭”。最初执行的脚本,或者它是否暂时隐藏到另一个(外部)脚本中。这使得程序员可以灵活地使脚本的行为不同,如果它直接执行而不是外部调用。

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

  • 打开xy.py作为&#39; home&#39;文件;在"__main__"变量中将其称为__name__
  • 使用__name__ == "ab.py"导入并打开文件。
  • 哦,一个功能。我记得那个。
  • 好的,功能a();我刚学会了这个。打印&#39; ab文件中的功能&#39;。
  • 文件结束;回到"__main__"
  • 哦,一个功能。我记得那个。
  • 另一个。
  • 功能x();好的,打印&#39; 外围任务:可能在其他项目中很有用&#39;。
  • 这是什么?一个if声明。好吧,条件已经满足(变量__name__已设置为"__main__"),因此我将输入main()函数并打印&#39; main功能:这是行动&#39;。

底部两行表示:&#34;如果这是"__main__"或&#39; home&#39;脚本,执行名为main()&#34;的函数。这就是为什么您会在顶部看到def main():块的原因,其中包含脚本功能的主要流程。

  

为什么要实现这个?

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

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

  

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

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

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

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

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

答案 7 :(得分:45)

当我们的模块中存在某些语句(M.py)时,我们希望在它作为main(非导入)运行时执行,我们可以将这些语句(测试用例,打印语句)放在这个if阻止。

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

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

答案 8 :(得分:35)

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

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

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

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

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

答案 9 :(得分:35)

简而言之,__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__告诉我们哪些代码是&#39;主要&#39;模块。 这很棒,因为你可以编写代码而不必担心C / C ++中的结构问题,如果文件没有实现主要的&#39;函数然后它不能被编译为可执行文件,如果是,它就不能用作库。

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

Complicated importing in C

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

Elegant importing in Python

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

答案 10 :(得分:32)

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

答案 11 :(得分:29)

考虑:

if __name__ == "__main__":
    main()

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

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

答案 12 :(得分:25)

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

  

什么是__name__

__name__DunderAlias - 可以被视为全局变量(可从模块访问),其工作方式与global类似。

这是type(__name__)所示的字符串(如上所述全局)(产生<class 'str'>),并且是Python 3Python 2版本的内置标准。

  

<强>其中:

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

<强>解释

>>> print(__name__)
__main__
>>>

<强>脚本:

test_file.py

print(__name__)

导致__main__

模块或包装:

somefile.py:

def somefunction():
    print(__name__)

test_file.py:

import somefile
somefile.somefunction()

导致somefile

请注意,在包或模块中使用时,__name__将获取文件的名称。没有给出实际模块或包路径的路径,但它有自己的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__或从中导入的文件名。

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

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

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

  

<强>模块:

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

  

变种:

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

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

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

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

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

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

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

答案 13 :(得分:21)

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

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

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

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

答案 14 :(得分:20)

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

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

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

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

答案 15 :(得分:19)

系统(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 ”。

希望这会有所帮助。

答案 16 :(得分:16)

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

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

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

答案 17 :(得分:16)

if __name__ == '__main__': 下的代码仅在将模块作为脚本调用时才会执行。

作为示例,请考虑以下模块my_test_module.py

# my_test_module.py

print('This is going to be printed out, no matter what')

if __name__ == '__main__':
    print('This is going to be printed out, only if user invokes the module as a script')

第一种可能性:将my_test_module.py导入另一个模块

# main.py

import my_test_module

if __name__ == '__main__':
    print('Hello from main.py')

现在,如果您调用main.py

python main.py 

>> 'This is going to be printed out, no matter what'
>> 'Hello from main.py'

请注意,仅执行print()中的顶级my_test_module语句。


第二种可能性:以脚本的形式调用my_test_module.py

现在,如果您将my_test_module.py作为Python脚本运行,则将执行两个print()语句:

python my_test_module.py

>>> 'This is going to be printed out, no matter what'
>>> 'This is going to be printed out, only if user invokes the module as a script'

有关更全面的说明,您可以read this blog post

答案 18 :(得分:14)

原因

if __name__ == "__main__":
    main()

主要是为了避免import lock引起的having code directly imported问题。如果您的文件被直接调用(这是main()情况),您希望__name__ == "__main__"运行,但如果您的代码已导入,则导入器必须从真正的主模块输入您的代码以避免导入锁定问题

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

答案 19 :(得分:13)

考虑:

print __name__

上述输出为__main__

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

以上陈述属实,并打印“直接方法”。假设他们在另一个类中导入了这个类,它不会打印“direct method”,因为在导入时,它会设置__name__ equal to "first model name"

答案 20 :(得分:13)

我在本页的所有答案中都读了很多东西。我会说,如果您知道这件事,那么您肯定会理解这些答案,否则,您仍然会感到困惑。

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

  1. import a操作实际上运行可以在“ a”中运行的所有内容

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

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

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

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

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

答案 21 :(得分:12)

  

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

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

答案 22 :(得分:7)

此答案适用于学习Python的Java程序员。 每个Java文件通常包含一个公共类。您可以通过两种方式使用该类:

  1. 从其他文件调用该类。您只需要将其导入调用程序中即可。

  2. 单独运行类,以进行测试。

对于后一种情况,该类应包含一个公共的静态void main()方法。在Python中,此目的由全局定义的标签'__main__'来实现。

答案 23 :(得分:5)

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

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

通常用于测试。

答案 24 :(得分:5)

如果python解释器正在运行特定模块,则__name__全局变量将具有值"__main__"

  def a():
      print("a")
  def b():
      print("b")

  if __name__ == "__main__": 

          print ("you can see me" )
          a()
  else: 

          print ("You can't see me")
          b()

当您运行此脚本时,会打印您可以看到我

a

如果您将此文件导入A到文件B并执行文件B,则文件A中的if __name__ == "__main__"变为false,因此它将打印您看不到我

b

答案 25 :(得分:4)

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

答案 26 :(得分:4)

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

if __name__ == "__main__":
       #do something

这意味着如果正在执行的文件的名称作为源文件运行并且NOT A MODULE,那么它将运行其中的代码,这可以通过一个简单的例子来证明。创建两个 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__ 为什么?因为文件作为 ma​​in 源运行,如果你执行 print(foo.__name__) 它会打印 foo 因为 __name__ 变量的默认值是文件的名称,并且默认我的意思是您也可以更改它以执行此操作只需转到 foo.py 并执行此操作 __name__ = "name" 然后当您运行该文件时例如

__name__ = "hello world"
print(__name__)

然后输出将是

hello world

答案 27 :(得分:3)

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

假设您有两个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是运行的主文件),那么只有代码被执行。

答案 28 :(得分:3)

Python中的每个模块都有一个名为 name 的特殊属性。当模块作为主程序执行时(例如运行python foo.py),名称属性的值设置为“ 主要”。否则,名称的值将设置为调用该模块的模块的名称。

答案 29 :(得分:3)

如果名称 ==&#39; 主要&#39;:

我们经常看到__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__

答案 30 :(得分:2)

简单来说,这是运行 C 编程语言中的文件main之类的文件的入口点。

答案 31 :(得分:1)

python中的每个模块都有一个称为 name 的属性。当模块直接运行时,名称属性的值为“ 主要”。否则, name 的值就是模块的名称。

简短说明的小例子。

#Script test.py

apple = 42

def hello_world():
    print("I am inside hello_world")

if __name__ == "__main__":
    print("Value of __name__ is: ", __name__)
    print("Going to call hello_world")
    hello_world()

我们可以直接执行为

python test.py  

输出

Value of __name__ is: __main__
Going to call hello_world
I am inside hello_world

现在假设我们从其他脚本中调用上述脚本

#script external_calling.py

import test
print(test.apple)
test.hello_world()

print(test.__name__)

执行此操作

python external_calling.py

输出

42
I am inside hello_world
test

因此,上面的解释是,当您从其他脚本调用测试时,如果test.py中的循环 name 不会执行。

答案 32 :(得分:1)

PYTHON主要功能是任何程序的起点。当程序运行时,python解释器将顺序运行代码。仅当主函数作为Python程序运行时才执行...

def main():
     print ("i am in the function")
print ("i am out of function")

运行脚本显示时:

i am out of function

,而不是代码“我在函数中” 这是因为我们没有声明调用函数“ if__name __ ==” main “。 如果您使用它:

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


if __name__ == "__main__":
    main()

print ("i am out of function")

输出等于

i am in the function
i am out of function

在Python中,“ if__name __ ==“ 主要”允许您将Python文件作为可重用模块或独立程序运行。

当Python解释器读取源文件时,它将执行其中找到的所有代码。 当Python将“源文件”作为主程序运行时,它将特殊变量( name )设置为具有值(“ main ”)。

执行main函数时,它将读取“ if”语句,并检查 name 是否等于 main

在Python中,“ if__name __ ==“ 主要”允许您将Python文件作为可重用模块或独立程序运行。

答案 33 :(得分:1)

简单地说:

Df_Sub1 # Var1 Var2 Var3 #Line1 1 2 3 #Line2 3 4 5 Df_Sub2 # Var3 Var4 #Line1 3 4 #Line2 5 6 Df_Sub3 # Var5 Var6 Var7 #Line1 5 6 7 #Line2 7 8 9 下看到的代码仅在将python文件作为“ python example1.py”执行时才会被调用。

但是,如果您希望将python文件“ example1.py”作为模块导入以与另一个python文件(例如“ example2.py”)一起使用,则if __name__ == "__main__":下的代码将无法运行或不起作用。

答案 34 :(得分:1)

if __name__ = "__main__" 意味着如果你像 python foo.py 这样正常运行 python 文件,它会将特殊变量 __name__ 分配给 "__main__" 但如果你像“ import foo" 它会将 __name__ 分配给 "foo" 并且不会运行该函数。

答案 35 :(得分:1)

我是 Python 初学者,但我想写在这里。

假设我在维基百科上编写了用于网页抓取的函数和类 当然,这可能不是一个很好的例子 我想在另一个程序中使用这些函数而不重写它

好吧,我导入它们,但在该文件的末尾 我把 __ 名称 __ = '__ main __'

当我们导入一个模块时,里面的所有代码都是从头到尾执行的 但是当它达到条件时,它不会运行func,fucn2和...,这是维基百科scrape

在全局范围内 Python __ name __ 被定义为 '__ main __' 用于当前程序

当我们导入一个模块时,它被定义为我们当前程序命名空间中的一个变量 和当前程序 __ 名称 __ 是 '__ main __'

#test.py
def func():
    #do somthing
    pass
def func2():
    #do somthing
    pass
print('The program name is set to',globals()['__name__'])

if __name__=='__main__':
    #in current program __name__ is equal '__main__' 
    func('https://www.wikipedia.org')
    func2('https://www.wikipedia.org')
    #or do more job
    
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 madule
inside of current
__main__
<module 'test1' from 'C:\\users\\ir\\appdata\\local\\programs\\python\\python38\\lib\\test1.py'>

答案 36 :(得分:0)

您可以通过以下简单示例检查特殊变量__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

答案 37 :(得分:0)

当你执行模块(源文件)时,if-condition检查模块是直接调用还是从另一个源文件调用。这里直接表示不导入。

如果直接调用执行,模块名设置为“main”,然后执行if块内的代码。