这段代码实际上在做什么?
当你执行
xy.py 时,你导入了
ab。导入语句在导入时运行模块,因此在
xy 的其余部分之前执行了
ab 的操作。完成 ab 后,它继续执行 xy。
解释器使用
__name__
跟踪正在运行的脚本。无论你给脚本命名为什么,当你运行一个脚本时,解释器都会将其称为
"__main__"
。这就是它跟踪哪个脚本是主文件的方式,也就是在调用另一个脚本后返回的脚本(你可能会说是“主页”脚本)。
从这个“主”脚本调用的任何其他脚本都被分配为其文件名作为其
__name__
。因此,
if __name__ == "__main__" :
这一行是解释器测试以确定它是否在运行它正在查看(解析)的脚本,还是暂时窥视另一个脚本。这使得程序员可以灵活地让脚本在外部调用时表现出不同的行为。
为了理解发生了什么,请首先关注未缩进的行以及它们在脚本中出现的顺序。请记住,函数或
def
块本身不会执行任何操作,直到它们被调用。如果解释器自言自语,可能会想到什么:
- 打开xy.py。
- 使用
__name__
ab.py导入并打开文件。
- 哦,一个函数。我会记住的。
- 好的,函数a(); 我刚学会了。我猜我现在要打印了。
- 文件结束; 回到
'__main__'
!
- 哦,一个函数。我会记住的。
- 又一个。
- 函数x(); 好的,打印's'。
- 这是什么?一个
if
语句。嗯,条件已经满足(变量__name__
已设置为'__main__'
),所以我将打印'b function'。
然而,我认为您没有正确使用它。可能有例外情况,但底部两行应该是:
if __name__ == "__main__":
main()
...这意味着“如果这是‘main’或主脚本,则执行名为main()
的函数。这就是为什么你会看到一个def main():
块在顶部,其中包含脚本功能的主要流程。
我们为什么要实现这个?
还记得我之前说过的导入语句吗?当你导入一个模块时,它不仅仅是“识别”它并等待进一步的指令。它实际上运行脚本中包含的所有可执行操作。因此,将脚本的主要内容放入main()
函数中有效地隔离它,使其处于孤立状态,以便在被另一个脚本导入时不能立即运行。
再次强调,会有例外情况,但通常做法是main()
通常不会被外部调用。所以你可能会想到另一个问题:如果我们不调用main()
,那么我们为什么还要调用脚本呢?这是因为许多人使用独立运行的函数来构建自己的脚本。然后在脚本的其他位置调用它们。这就带我来到了这个问题:
我们的代码即使没有它也可以工作
是的,你说得对。这些单独的函数可以从不包含在main()
函数内部的内联脚本中调用。如果你习惯于(就像我在编程的早期学习阶段一样)构建内联脚本,以便精确地完成所需的任务,并且如果你需要再次执行该操作,你会尝试再次弄清楚它 - 那么,你可能不习惯代码的这种内部结构,因为它更复杂,阅读起来也不太直观。
但是,这可能是一个脚本,不能从外部调用其函数,因为如果这样做,它将开始计算和分配变量。而且,如果你试图重用一个函数,你的新脚本很可能与旧脚本密切相关,可能存在冲突的变量。
我应该顺便说一下,这个问题包含了kindall的一个答案,最终帮助我理解了-为什么,而不是如何。不幸的是,它被标记为这个问题的重复,我认为这是一个错误。(我是这个网站的新手,所以还不能标记它;如果你同意我的观点,请标记它以引起更多管理员的注意。)
main(String [] args)
一样。 - Radinator