什么意思 - python__name__用法




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

if __name__ == "__main__":怎么办?

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

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

python mycode.py

否则,匿名全局命名空间将为其__name__分配值'__main__'

因此,包括最后一行

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

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

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

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

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

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__模块的解释中找到。 该文字指出:

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

if __name__ == '__main__':
    main()

如果name ==' main ':

我们__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__

__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__"


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


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

什么是__name__

__name__DunderAlias - 可以被认为是一个全局变量(可以从模块访问),并以类似于global

它是一个字符串(全局如上所述),由type(__name__) (产生<class 'str'> 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

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

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


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

创建一个文件, a.py

print(__name__) # It will print out __main__

只要该文件直接运行显示这是主文件, __name__总是等于__main__

在同一目录中创建另一个文件b.py

import a  # Prints a

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

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

# Code to be run when imported into another python file

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

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

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

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


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

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

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

python threading_example.py

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

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

有关其他详细信息,请参阅此页面

注意 (由Stainsor提供):如果将代码放在函数定义之前,它将在main之前执行。

print("This code executes before main.") 

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

def functionB():
    print("Function B")

if __name__ == '__main__':
    functionA()
    functionB()

如果此模块确实是主模块,则此代码会导致:

This code executes before main. 
Function A 
Function B

如果这个模块不是主要的,你得到:

This code executes before main. 

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

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

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

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


最近,我在创建python(深度学习)课程时遇到了这个问题,并且根据我的理解并同意上面列出的顶级解释,我将详细说明

__name__=="__main__"

有时我们在.py文件中构造一个类,并在该类中定义了许多函数。但是我们不想为了一个目的而处理所有这些类函数。例如,用于创建类并定义一些用于数据创建的函数(.npy文件),而一些用于数据加载。所以,如果我们定义

__name__=="__main__"

XXX = CLASS_NAME()

xxx.create_data()

意味着如果我们调用.py文件,那么它只会创建数据而不会处理其他类函数。其他类函数(数据加载)也可以由其他类导入。


简而言之, __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__告诉我们哪个代码是'main'模块。 这很好,因为你可以只编写代码而不必担心C / C ++中的结构问题,如果文件没有实现'main'函数那么它就不能编译为可执行文件,如果是,它不能用作库。

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

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

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


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

希望这会有所帮助。


考虑:

print __name__

上面的输出是__main__

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

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


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

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

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

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

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


通过将脚本作为命令传递给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__"


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

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





idioms