1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # 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解释器读取源文件时,它会做两件事:
它设置了一些特殊的变量,比如
它执行文件中找到的所有代码。
让我们看看这是如何工作的,以及它如何与您关于
代码示例
让我们使用稍微不同的代码示例来研究导入和脚本是如何工作的。假设以下内容在一个名为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # 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读取源文件时,它首先定义几个特殊的变量。在本例中,我们关心的是
当您的模块是主程序时
如果您将模块(源文件)作为主程序运行,例如。
1 | python foo.py |
解释器将硬编码字符串
1 2 3 | # It's as if the interpreter inserts this at the top # of your module when run as the main program. __name__ ="__main__" |
当模块被其他模块导入时
另一方面,假设另一个模块是主程序,它导入了您的模块。这意味着在主程序或主程序导入的其他模块中有这样的语句:
1 2 | # Suppose this is in some other main program. import foo |
在本例中,解释器将查看模块的文件名
1 2 3 | # It's as if the interpreter inserts this at the top # of your module when it's imported from another module. __name__ ="foo" |
执行模块代码
在设置了特殊变量之后,解释器执行模块中的所有代码,每次执行一条语句。您可能想在代码示例旁边打开另一个窗口,这样您就可以按照这个解释来操作了。
总是
它输出字符串
它加载
1 2 3 | # Find and load a module given its string name,"math", # then assign it to a local variable called math. math = __import__("math") |
它打印字符串
它执行
它打印字符串
它执行第二个
它打印字符串
只有当你的模块是主程序时
如果您的模块是主程序,那么它将看到只有当您的模块被另一个模块导入时
(相反)如果您的模块不是主程序,而是由另一个程序导入的,那么总是
它将在两种情况下打印字符串总结
总之,以下是两种情况下的打印结果:
1 2 3 4 5 6 7 8 | # 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 |
1 2 3 4 5 6 | # What gets printed if foo is imported as a regular module before import before functionA before functionB before __name__ guard after __name__ guard |
它为什么这样工作?
你可能会很自然地想知道为什么会有人想要这个。嗯,有时候您想要编写一个
您的模块是一个库,但是您希望有一个脚本模式,在其中运行一些单元测试或演示。
您的模块只作为一个主程序使用,但它有一些单元测试,测试框架通过导入
您的模块主要用作一个主程序,但它也为高级用户提供了一个程序员友好的API。
除了这些例子之外,用Python运行脚本只需设置一些神奇的变量并导入脚本,这是非常优雅的。"运行"脚本是导入脚本模块的副作用。
精神食粮
问:我可以有多个
假设下面的代码在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # 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") |
现在,计算一下如果删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # 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 2 3 4 5 6 7 8 9 10 | # Suppose this is in foo4.py __name__ ="__main__" def bar(): print("bar") print("before __name__ guard") if __name__ =="__main__": bar() print("before __name__ guard") |
当通过将脚本作为命令传递给Python解释器来运行脚本时,
1 | python myscript.py |
所有缩进级别为0的代码都将执行。已经定义的函数和类已经定义,但是它们的代码都没有运行。与其他语言不同,没有自动运行的
在本例中,顶层代码是一个
1 2 | if __name__ =="__main__": ... |
如果您的脚本被导入到另一个模块中,它的各种函数和类定义将被导入,它的顶级代码将被执行,但是上面的
1 2 3 4 5 6 7 8 9 10 | # 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") |
1 2 3 4 5 6 7 8 9 10 | # 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") |
现在,如果您调用解释器as
1 | python one.py |
输出将是
1 2 | top-level in one.py one.py is being run directly |
如果你运行
1 | python two.py |
你得到
1 2 3 4 5 | 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 |
因此,当加载模块
创建以下文件。
1 2 | # a.py import b |
和
1 2 3 4 5 | # b.py print"Hello World from %s!" % __name__ if __name__ == '__main__': print"Hello World again from %s!" % __name__ |
运行它们会得到如下输出:
1 2 | $ python a.py Hello World from b! |
可以看到,当导入模块时,Python将该模块中的
1 2 3 | $ python b.py Hello World from __main__! Hello World again from __main__! |
可以看到,当执行一个文件时,Python将该文件中的
What does the if __name__ =="__main__": do?
概述基本知识:
作为程序入口点的模块中的全局变量
因此,只有当模块是程序的入口点时,
它允许模块中的代码可以被其他模块导入,而不需要在导入时执行下面的代码块。
我们为什么需要这个?
开发和测试您的代码假设您正在编写一个用于模块的Python脚本:
1 2 | def do_important(): """This function does something very important""" |
您可以通过在底部添加这个函数调用来测试模块:
1 | do_important() |
然后运行它(在命令提示符下),如下所示:
1 | ~$ python important.py |
问题
但是,如果您想将模块导入到另一个脚本:
1 | import important |
在导入时,将调用
1 | # do_important() # I must remember to uncomment to execute this! |
然后您必须记住是否注释掉了测试函数调用。这种额外的复杂性意味着您可能会忘记,从而使您的开发过程更加麻烦。
一个更好的方法
在导入的模块中,它是该模块的名称。
但是在主模块(或交互式Python会话,即解释器的Read、Eval、Print Loop或REPL)中,您可以运行从它的
所以如果你在执行前检查:
1 2 | if __name__ =="__main__": do_important() |
使用上面的代码,您的代码只会在您将其作为主模块运行时执行(或者有意地从另一个脚本调用它)。
一个更好的方法不过,有一种python式的方法可以改进这一点。
如果我们想从模块外部运行这个业务流程,该怎么办?
如果我们把我们开发和测试时想要练习的代码放在这样一个函数中,然后立即检查
1 2 3 4 5 6 7 8 9 10 11 12 | 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() |
现在我们有了模块末尾的最后一个函数,如果我们将模块作为主模块运行,它将运行。
它将允许在不运行
1 2 | import important important.main() |
在Python文档中对
This module represents the (otherwise anonymous) scope in which the
interpreter’s main program executes — commands read either from
standard input, from a script file, or from an interactive prompt. It
is this environment in which the idiomatic"conditional script" stanza
causes a script to run:
1
2 if __name__ == '__main__':
main()
What does if __name__ =="__main__": do?
但是,作为唯一的特殊情况,在您运行的任何Python进程中,如mycode.py:
1 | python mycode.py |
否则匿名的全局名称空间将
因此,包括最后一行
1 2 | if __name__ == '__main__': main() |
在mycode.py脚本的末尾,当它是由Python进程运行的主要入口点模块时,
将导致脚本唯一定义的
使用这种结构的另一个好处是:您还可以将代码作为模块导入另一个脚本中,然后在程序决定:
1 2 3 | import mycode # ... any amount of other code mycode.main() |
这里有很多关于代码机制的不同观点,比如"如何",但是对我来说,在我理解"为什么"之前,这些观点都没有任何意义。这对新程序员尤其有用。
把文件"ab.py":
1 2 3 | def a(): print('A function in ab file'); a() |
第二个文件"xy.py":
1 2 3 4 5 6 7 8 | 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() |
What is this code actually doing?
当您执行
解释器跟踪使用
从这个
让我们逐步了解上面的代码,首先关注未缩进的行以及它们在脚本中出现的顺序。请记住,函数(或
下面两行表示:"如果这是
Why implement this?
还记得我之前说过的导入语句吗?当您导入一个模块时,它不仅仅"识别"它并等待进一步的指令——它实际上运行脚本中包含的所有可执行操作。因此,将脚本的主体放入
同样,也会有例外,但是通常的做法是
But the code works without it
是的,这是正确的。这些单独的函数可以从没有包含在
但是这个脚本可能不能在外部调用它的函数,因为如果调用了函数,它将立即开始计算和分配变量。而且,如果您试图重用一个函数,那么您的新脚本可能与旧脚本紧密相关,因此会出现冲突的变量。
通过分离独立的函数,您可以通过将它们调用到另一个脚本中来重用以前的工作。例如,"的例子。py"可能导入"xy。和调用
(顺便提一句,这个问题的答案来自@kindall,它最终帮助我理解了为什么,而不是如何。不幸的是,它被标记为这个的复制品,我认为这是一个错误。)
当我们的模块(
默认情况下(当模块作为main运行时,不导入),
简而言之,使用这个"
让我们从一个更抽象的角度来看这个问题的答案:
假设我们在x.py中有这样的代码:
1 2 3 4 5 | ... <Block A> if __name__ == '__main__': <Block B> ... |
当我们运行"x.py"时,将运行块A和块B。
但是当我们运行另一个模块y时,只是block A(而不是block B)在运行。例如,其中x。导入y,然后从那里运行代码(就像"x"中的函数一样)。py"是从y.py中调用的。
简单地说,
如果我们有两个脚本;
1 2 | #script1.py print"Script 1's name: {}".format(__name__) |
和
1 2 3 | #script2.py import script1 print"Script 2's name: {}".format(__name__) |
执行script1的输出为
1 | Script 1's name: __main__ |
执行script2的输出为:
1 2 | Script1's name is script1 Script 2's name: __main__ |
如您所见,
假设您编写了一个非常有用的Python脚本,并且实现了大量用于其他目的的函数。如果我想使用它们,我可以导入您的脚本并在不执行程序的情况下使用它们(假定您的代码只在
箭头是导入链接。对于三个试图包含前面模块代码的模块,每个模块有6个文件(包括9个实现文件)和5个链接。这使得将其他代码包含到C项目中变得非常困难,除非它被特别编译为一个库。现在想象一下Python:
您编写一个模块,如果有人想使用您的代码,他们只需导入它,
当您交互式地运行Python时,局部
1 2 3 4 5 6 7 8 | 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. |
考虑:
1 2 | if __name__ =="__main__": main() |
它检查Python脚本的
但是,如果模块使用Python脚本,则会执行
在解释关于
What is
__name__ ?
它是一个由
Where:
它不仅可以在脚本中使用,还可以在解释器和模块/包中找到。
翻译:
1 2 3 | >>> print(__name__) __main__ >>> |
脚本:
test_file.py:
1 | print(__name__) |
导致
模块或包:
somefile.py:
1 2 | def somefunction(): print(__name__) |
test_file.py:
1 2 | import somefile somefile.somefunction() |
导致
注意,当在包或模块中使用时,
您应该看到,在主文件(或程序)所在的位置
Practice:
作为一个变量意味着它的值可以被覆盖("can"并不意味着"should"),覆盖
通常假定
例子:
1 2 3 4 5 6 7 | >>> __name__ = 'Horrify' # Change default from __main__ >>> if __name__ == 'Horrify': print(__name__) ... >>> else: print('Not Horrify') ... Horrify >>> |
一般来说,在脚本中包含
Now to answer
if __name__ == '__main__' :
现在我们知道
这意味着如果
如果
这告诉我们,如果运行的文件是主文件(或者直接从解释器运行),那么必须执行该条件。如果它是一个包,那么它就不应该是,并且值将不是
Modules:
Variants:
也可以用
只有当文件是模块或包时才执行:
1 2 | if __name__ != '__main__': # Do some useful things |
运行一个条件,如果文件是主要的,另一个条件,如果不是:
1 2 3 4 | if __name__ == '__main__': # Execute something else: # Do some useful things |
您还可以使用它在包和模块上提供可运行的帮助函数/实用程序,而无需使用库。
它还允许从命令行作为主要脚本运行模块,这也非常有用。
我认为最好是用简单的语言深入地回答这个问题:
因此,当模块作为主程序运行时,
当从命令行调用Python文件时,它是一个特殊的函数。这通常用于调用"main()"函数或执行其他适当的启动代码,例如命令行参数处理。
它可以用几种方式来写。另一个原因是:
1 2 3 4 5 | def some_function_for_instance_main(): dosomething() __name__ == '__main__' and some_function_for_instance_main() |
我并不是说您应该在生产代码中使用它,但是它说明了
系统(Python解释器)为源文件(模块)提供了许多变量。您可以在任何时候获得它们的值,因此,让我们关注于……name__变量/属性:
当Python加载源代码文件时,它将执行其中找到的所有代码。(注意,它没有调用文件中定义的所有方法和函数,但是它确实定义了它们。)
在解释器执行源代码文件之前,它为该文件定义了一些特殊的变量;是Python为每个源代码文件自动定义的特殊变量之一。
如果Python将这个源代码文件加载为主程序(即您运行的文件),那么它将为这个文件设置一个特殊的……name__变量,使其值为"……main__"。
如果这是从另一个模块导入的,则将将该模块的名称设置为_name__。
在你的例子中
1 2 3 4 | 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)) |
表示代码块:
1 2 3 | lock = thread.allocate_lock() thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock)) thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock)) |
只会在直接运行模块时执行;如果另一个模块调用/导入代码块,代码块将不会执行,因为在该特定实例中,_name__的值将不等于"main"。
希望这能有所帮助。
1 2 3 | if __name__ =="__main__": # Execute only if run as a script main() |
的原因
1 2 | if __name__ =="__main__": main() |
主要是为了避免由于直接导入代码而产生的导入锁问题。如果您的文件是直接调用的(这是
其副作用是您自动登录到支持多个入口点的方法。您可以使用
我在这一页上读了很多答案。我想说的是,如果你知道这件事,你肯定会理解这些答案,否则,你仍然会感到困惑。
简而言之,你需要知道以下几点:
由于第1点,您可能不希望在导入时所有内容都在"a"中运行
要解决第2点中的问题,python允许您进行条件检查
根据python为每个模块设置变量
python的特殊之处在于第4点!剩下的只是基本的逻辑。
You can make the file usable as a script as well as an importable module.
py(一个名为
1 2 3 4 5 6 7 8 9 10 11 12 | # 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
考虑:
1 | print __name__ |
上面的输出是
1 2 | if __name__ =="__main__": print"direct method" |
以上语句为真,打印"direct method"。假设他们在另一个类中导入这个类,它不会打印"direct method",因为在导入时,它会设置
如果这个.py文件被其他.py文件导入,那么"the If语句"下的代码将不会执行。
如果这个.py在shell下由
它通常是为测试而编写的。
这个答案适用于学习Python的Java程序员。每个Java文件通常包含一个公共类。你可以用两种方式使用这个类:
从其他文件调用该类。你只需要在调用程序中导入它。
为了测试的目的,单独运行类。
对于后一种情况,类应该包含一个公共静态void main()方法。在Python中,这个目的由全局定义的标签
创建一个文件a.py:
1 | print(__name__) # It will print out __main__ |
当直接运行该文件时,
创建另一个文件b。,在同一目录下:
1 | import a # Prints a |
运行它。它将输出a,即。,即导入的文件的名称。
因此,要显示同一个文件的两种不同行为,这是一个常用的技巧:
1 2 3 4 | # Code to be run when imported into another python file if __name__ == '__main__': # Code to be run only when run directly |
if name == 'main':
我们经常看到
它检查模块是否被导入。
换句话说,只有当代码直接运行时,才会执行
让我们看看它是如何使用一个简单的代码打印模块的名称:
1 2 3 4 5 6 7 | # test.py def test(): print('test module name=%s' %(__name__)) if __name__ == '__main__': print('call test()') test() |
如果我们直接通过
1 2 | call test() test module name=__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是正在运行的主文件),然后只执行该代码。
简单地说,它是像C编程语言中的