发布于2019-08-19 21:36 阅读(1450) 评论(0) 点赞(26) 收藏(4)
怎么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 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"
设置特殊变量后,解释器将执行模块中的所有代码,一次执行一个语句。您可能希望使用代码示例打开另一个窗口,以便您可以按照此说明进行操作。
总是
它打印字符串"before import"
(不带引号)。
它加载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")
它打印字符串"before functionA"
。
它执行def
块,创建一个函数对象,然后将该函数对象分配给一个名为的变量functionA
。
它打印字符串"before functionB"
。
它执行第二个def
块,创建另一个函数对象,然后将其分配给一个名为的变量functionB
。
它打印字符串"before __name__ guard"
。
仅当您的模块是主程序时
__name__
确实设置为"__main__"
并且它调用两个函数,打印字符串"Function A"
和"Function B 10.0"
。仅当您的模块被另一个导入时
__name__
将是"foo"
,而不是"__main__"
,它将跳过if
语句的主体。总是
"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.
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")
# Suppose this is in foo4.py
__name__ = "__main__"
def bar():
print("bar")
print("before __name__ guard")
if __name__ == "__main__":
bar()
print("after __name__ guard")
作者:黑洞官方问答小能手
链接:https://www.pythonheidong.com/blog/article/48890/15b9eec4760ffb54b972/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!