这是什么,为什么应该包括一个 if 声明?

if __name__ == "__main__":
    print("Hello, World!")

如果你试图关闭一个问题,有人应该使用这个字符,而不是,考虑关闭作为一个复制为什么Python在我进口时运行我的模块,而我如何停止它? 问题,有人只是没有呼叫任何功能,或者错误地等待一个名为主的功能将自动作为一个输入点,使用为什么没有主()功能运行。


当前回答

如果 __name__ ==“__main__”意味着如果您正常运行 Python 文件如 python foo.py,则将特殊变量 __name__ 归分为“__main__”。

但是,如果您正在导入文件如“导入 foo”,则将 __name__ 归分为“foo”并且不会运行函数。

其他回答

短答

它是字符串代码,保护用户在他们不打算时偶然提起脚本,这里有一些常见问题,当警卫被忽略了一个脚本:

长答

每当Python翻译器阅读源文件时,它都会做两件事:

让我们看看它是如何工作的,以及它是如何与您的问题有关的 __name__ 检查我们总是看到在 Python 脚本。

让我们使用一个稍微不同的代码样本来探索进口和脚本是如何工作的。

# Suppose this is foo.py.

print("before import")
import math

print("before function_a")
def function_a():
    print("Function A")

print("before function_b")
def function_b():
    print("Function B {}".format(math.sqrt(100)))

print("before __name__ guard")
if __name__ == '__main__':
    function_a()
    function_b()
print("after __name__ guard")

当您的模块是主要程序时

python foo.py

# 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

# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"

# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")

如果您的模块是主要程序,那么它会看到 __name__ 实际上设置为“__main__”并称为两个功能,打印线“函数 A”和“函数 B 10.0”。

只有当您的模块被另一个模块进口时

总是

它将在两种情况下打印“ __name__ 警卫”字符串。

总结

# What gets printed if foo is the main program
before import
before function_a
before function_b
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 function_a
before function_b
before __name__ guard
after __name__ guard

為什麼它會這樣工作?

# Suppose this is foo2.py.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters

def function_a():
    print("a1")
    from foo2 import function_b
    print("a2")
    function_b()
    print("a3")

def function_b():
    print("b")

print("t1")
if __name__ == "__main__":
    print("m1")
    function_a()
    print("m2")
print("t2")
      

# Suppose this is foo3.py.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters

def function_a():
    print("a1")
    from foo3 import function_b
    print("a2")
    function_b()
    print("a3")

def function_b():
    print("b")

print("t1")
print("m1")
function_a()
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")

所有答案都解释了功能性,但我会给出一个例子它的使用,这可能有助于进一步清理这个概念。

假设你有两个 Python 文件, a.py 和 b.py. 现在, a.py 输入 b.py. 我们运行 a.py 文件,其中输入 b.py 代码首先执行。

在 b.py 代码中,有一些代码是专属于 b.py 文件,我们不希望任何其他文件(除了 b.py 文件),已进口了 b.py 文件,运行它。

如果它是主要文件(即,b.py)运行代码,在这种情况下它不是(a.py是主要文件运行),那么只有代码被执行。

如果此.py 文件是由其他.py 文件进口的,则如果声明下的代码将不会被执行。

如果这个.py 是由 python 运行这个_py.py 在 Shell 下, 或在 Windows 中双击, 该代码在 if 声明 下将执行。

通常是用来测试的。

简单的说法:

下面看到的代码如果 __name__ ==“__main__”:只有当您的 Python 文件作为 python 示例1.py 执行时才会被召回。

但是,如果您想将您的 Python 文件 example1.py 作为一个模块来与另一个 Python 文件一起工作,请说 example2.py,下面的代码如果 __name__ ==“__main__”:不会运行或采取任何效果。

# XXX FIXME: useless (see below)
if __name__ == "__main__":
    n = int(input('Write a number: '))
    a, b = 0, 1
    while b < n:
        a, b = b, a+b
    print('Fibonacci number %i: %i' % (n, b))

n = int(input('Write a number: '))
a, b = 0, 1
while b < n:
    a, b = b, a+b
print('Fibonacci number %i: %i' % (n, b))

如果你想能够进口纤维,第一个版本是无用的,也是,因为有用的代码在一个部分,它不会运行,当你进口这个文件(在这种情况下 __name__ 不会是“__main__”). 正确的设计在这种情况下将是恢复代码,以便有用的部分在一个功能,你可以运行,当你想要之后你已经进口它。

def main():
    n = int(input('Write a number: '))
    a, b = 0, 1
    while b < n:
        a, b = b, a+b
    print('Fibonacci number %i: %i' % (n, b))

if __name__ == "__main__":
    main()

事实上,更好的设计仍然是将可重复使用的部分(实际计算)与用户可见的输入/输出隔离:

def fibn(n: int) -> int:
    a, b = 0, 1
    while b < n:
        a, b = b, a+b
    return b

def main() -> None:
    n = int(input('Write a number: '))
    print('Fibonacci number %i: %i' % (n, fibn(n)))

if __name__ == "__main__":
    main()

现在,您可以从 Fib 进口 Fibn 并从执行此进口的代码呼叫 Fibn() 函数。

def 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__":
    main()

(不同于类似于C的语言,主要名称对Python没有具体的含义;但它是常见的公约使用它作为将运行的东西的名称。