python中def main是什么意思_如何理解Python中if__name__==“__main__”?它是什么意思,有什么用?...

如何理解Python中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__,然后

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

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

代码示例

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

#假设这是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__变量,即

#就像解释器在顶部插入它一样

作为主程序运行时模块的#。

__name__ =“__

main__”

当你的模块被另一个导入时

另一方面,假设某些其他模块是主程序,它会导入你的模块。这意味着在主程序或主程序导入的其他模块中有这样的声明:

#假设这是在其他一些主程序中。

导入foo

在这种情况下,解释器将查看模块的文件名foo.py,剥离.py,并将该字符串分配给模块的__name__变量,即

#就像解释器在顶部插入它一样

从其他模块导入模块时的#个。

__name__ =“foo”

执行模块的代码

设置特殊变量后,解释器将执行模块中的所有代码,一次执行一个语句。你可能希望使用代码示例打开另一个窗口,以便你可以按照此说明进行操作。

总是

它打印字符串“导入前”(不带引号)。

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

#找到并加载一个给定字符串名称“math”的模块,

#然后将其分配给名为math的局部变量。

math = __import __(“math”)

它打印字符串“在functionA之前”。

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

它打印字符串“在functionB之前”。

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

它打印字符串“在__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中运行脚本只是设置一些魔术变量并导入脚本是很优雅的。 “运行”脚本是导入脚本模块的副作用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值