__name__ ==“ __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))
福兹先生:

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

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

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

让我们看看它是如何工作的,以及它与您关于__name__Python脚本中经常看到检查问题的关系

代码样例

让我们使用一个稍有不同的代码示例来探索导入和脚本的工作方式。假设以下内容位于名为的文件中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交互程序读取源文件时,它首先定义一些特殊变量。在这种情况下,我们关心__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 functionA"

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

  3. 它输出字符串"before functionB"

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

  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 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文件,文件既可以被其他程序和/或模块用作模块,也可以作为主程序本身运行。例子:

  • 您的模块是一个库,但是您希望有一个脚本模式,在其中运行一些单元测试或演示。

  • 您的模块仅用作主程序,但具有一些单元测试,并且测试框架通过导入.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 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.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters

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")
  • 当用作脚本时,它将做什么?当作为模块导入时?
# Suppose this is in foo4.py
__name__ = "__main__"

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

if __name__ ==“ __main__”的位置:

替代 if __name__ == '__main__':

来自 if __name__ == "__main__" 的返回语句

如果__name__ =='__main__'函数调用

如何使用 if __name__ == '__main__':

python if __name__ ==“ __main__”:IndentationError:预期为缩进块

如果__name__ =='__main__'不起作用ipython

如果__name__ ==“ __main__”条件(带烧瓶/弹性豆茎)

如果在IPython中__name__ =='__main__'

如何测试或模拟“如果__name__ =='__main__'”内容

如何在“if __name__ == '__main__'”中模拟.patch 变量

使用python-multiprocessing与if __name__ =='__main__'相关的谜

使用 if __name__ == "__main__" 从其他文件调用函数:

将多个参数传递给 Python __name__=="__main__"

为什么不将__name__ =='__main__'放在模块的开头?

R是否等效于pythonic的“如果__name__ ==“ __main__”:main()“?

是否有C与Python等效:如果__name__ =='__main__':在文件顶部写入main()?

Python:如果__name__ =='__main__',则导入并初始化Argparse?

Python:如果__name__ =='__main__',则导入并初始化Argparse?

Pycharm“Python 控制台”中的 exec(open) 函数不执行“if __name__ == '__main__”块

如果__name__ =='__main__':语句下写很多代码是否常见?

在Python中调用getLogger之前,是否需要显式检查__name__ ==“ __main__”?

if __name__ == "__main__": 做什么?它是干什么用的?

在Python multiprocessing.Process中,我们是否必须使用`__name__ == __main__`?

如果__name__ =='__main__',则相当于python的node.js

仅当 __name__ == "__main__" 时才从 setuptools 运行设置函数?

在C ++中模拟__name__ == __main__是否导致错误“未定义类似函数的宏”

__name__="__main__" 里面和外面有什么不同?

Python:命令行,sys.argv,“如果__name__ =='__main__'”