Python中如果__name__ ==“ __main__”怎么办?

Python中如果__name__ ==“ __main__”怎么办?,第1张

Python中如果__name__ ==“ __main__”怎么办?

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

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

    __name__
    ,然后

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

让我们看看它是如何工作的,以及它与你有关

__name__
我们在Python脚本中经常看到的检查问题的关系。

代码样例

让我们使用稍微不同的代码示例来探索导入和脚本的工作方式。假设以下文件位于

foo.py

# Suppose this is foo.py.print("before import")import mathprint("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,剥离.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中的低级函数,它接受字符串并触发实际的导入):
# 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 programbefore importbefore functionAbefore functionBbefore __name__ guardFunction AFunction B 10.0after __name__ guard
# What gets printed if foo is imported as a regular modulebefore importbefore functionAbefore functionBbefore __name__ guardafter __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")


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4887762.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-12
下一篇 2022-11-12

发表评论

登录后才能评论

评论列表(0条)

保存