__name__ =="__main__"怎么办? [英] What does if __name__ == "__main__": do?

查看:124
本文介绍了__name__ =="__main__"怎么办?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下代码,if __name__ == "__main__":会做什么?

Given the following code, what does the if __name__ == "__main__": do?

# 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解释器读取源文件时,它就会做两件事:

Whenever the Python interpreter reads a source file, it does two things:

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

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

it executes all of the code found in the file.

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

Let's see how this works and how it relates to your question about the __name__ checks we always see in Python scripts.

让我们使用稍微不同的代码示例来探索导入和脚本的工作方式.假设以下内容位于名为foo.py的文件中.

Let's use a slightly different code sample to explore how imports and scripts work. Suppose the following is in a file called 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__变量.

您的模块是主程序时

如果您将模块(源文件)作为主程序运行,例如

If you are running your module (the source file) as the main program, e.g.

python foo.py

解释器会将硬编码的字符串"__main__"分配给__name__变量,即

the interpreter will assign the hard-coded string "__main__" to the __name__ variable, i.e.

# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__name__ = "__main__" 

您的模块是由另一个模块导入的

另一方面,假设其他模块是主程序,并且它将导入您的模块.这意味着在主程序中或主程序导入的其他模块中有这样的语句:

On the other hand, suppose some other module is the main program and it imports your module. This means there's a statement like this in the main program, or in some other module the main program imports:

# Suppose this is in some other main program.
import foo

解释器将搜索您的foo.py文件(以及搜索其他一些变体),并且在执行该模块之前,它将从import语句中将名称"foo"分配给__name__变量,即

The interpreter will search for your foo.py file (along with searching for a few other variants), and prior to executing that module, it will assign the name "foo" from the import statement to the __name__ variable, i.e.

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

执行模块的代码

设置特殊变量后,解释器将一次执行一个语句,执行模块中的所有代码.您可能需要在代码示例侧面打开另一个窗口,以便您可以按照以下说明进行操作.

Executing the Module's Code

After the special variables are set up, the interpreter executes all the code in the module, one statement at a time. You may want to open another window on the side with the code sample so you can follow along with this explanation.

始终

  1. 它显示字符串"before import"(不带引号).

它将加载math模块并将其分配给名为math的变量.这等效于用以下内容替换import math(请注意,__import__是Python中的一个低级函数,它接受字符串并触发实际的导入):

It loads the math module and assigns it to a variable called math. This is equivalent to replacing import math with the following (note that __import__ is a low-level function in Python that takes a string and triggers the actual import):

# 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".

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

It executes the def block, creating a function object, then assigning that function object to a variable called functionA.

它显示字符串"before functionB".

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

It executes the second def block, creating another function object, then assigning it to a variable called functionB.

它显示字符串"before __name__ guard".

仅当您的模块是主程序时

  1. 如果您的模块是主程序,那么它将看到__name__确实设置为"__main__",并且它将调用这两个函数,并打印字符串"Function A""Function B 10.0".
  1. If your module is the main program, then it will see that __name__ was indeed set to "__main__" and it calls the two functions, printing the strings "Function A" and "Function B 10.0".

仅当您的模块被另一个导入时

  1. (代替)如果您的模块不是主程序而是由另一个程序导入的,则__name__将是"foo",而不是"__main__",它将跳过主体if语句的内容.
  1. (instead) If your module is not the main program but was imported by another one, then __name__ will be "foo", not "__main__", and it'll skip the body of the if statement.

始终

  1. 在两种情况下都会打印字符串"after __name__ guard".

摘要

Summary

总而言之,这是两种情况下的打印内容:

In summary, here's what'd be printed in the two cases:

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

Why Does It Work This Way?

You might naturally wonder why anybody would want this. Well, sometimes you want to write a .py file that can be both used by other programs and/or modules as a module, and can also be run as the main program itself. Examples:

  • 您的模块是一个库,但是您希望使用脚本模式来运行某些单元测试或演示.

  • Your module is a library, but you want to have a script mode where it runs some unit tests or a demo.

您的模块仅用作主程序,但是它具有一些单元测试,并且测试框架通过导入.py文件(如脚本)并运行特殊的测试功能来工作.您不希望它只是因为正在导入模块而尝试运行脚本.

Your module is only used as a main program, but it has some unit tests, and the testing framework works by importing .py files like your script and running special test functions. You don't want it to try running the script just because it's importing the module.

您的模块主要用作主程序,但它也为高级用户提供了易于编程的API.

Your module is mostly used as a main program, but it also provides a programmer-friendly API for advanced users.

除了这些示例之外,可以优雅地用Python运行脚本只是设置一些魔术变量并导入脚本. 运行"脚本是导入脚本模块的副作用.

Beyond those examples, it's elegant that running a script in Python is just setting up a few magic variables and importing the script. "Running" the script is a side effect of importing the script's module.

  • 问题:我可以有多个__name__检查块吗?答:这样做很奇怪,但是语言不会阻止您.

  • Question: Can I have multiple __name__ checking blocks? Answer: it's strange to do so, but the language won't stop you.

假定foo2.py中包含以下内容.如果在命令行中说python foo2.py会怎样?为什么?

Suppose the following is in foo2.py. What happens if you say python foo2.py on the command-line? Why?

# 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")

  • 现在,弄清楚如果删除foo3.py中的__name__支票会发生什么情况:
    • Now, figure out what will happen if you remove the __name__ check in 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")
        

        这篇关于__name__ =="__main__"怎么办?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆