这里有很多关于代码机制的不同看法,比如“如何”,但对我来说,在我理解“为什么”之前,这一切都没有意义这对新程序员尤其有帮助。
获取文件“ab.py”:
def a():
print('A function in ab file');
a()
以及第二个文件“xy.py”:
import ab
def main():
print('main function: this is where the action is')
def x():
print ('peripheral task: might be useful in other projects')
x()
if __name__ == "__main__":
main()
这段代码到底在做什么?
当你执行
xy.py
,你
import ab
. import语句在导入时立即运行模块,因此
ab
的操作在
xy
一旦完成
ab公司
,它继续
xy型
.
解释器跟踪运行的脚本
__name__
. 当你运行一个脚本时,不管你给它起了什么名字,解释器都会调用它
"__main__"
,使其成为运行外部脚本后返回的主脚本或“主”脚本。
从这里调用的任何其他脚本
“主要”
将脚本的文件名指定为
__姓名__
(例如。,
__name__ == "ab.py"
). 因此,这条线
if __name__ == "__main__":
是解释器的测试,以确定它是在解释/解析最初执行的“home”脚本,还是临时窥视另一个(外部)脚本这就为程序员提供了灵活性,使脚本在直接执行与外部调用时有不同的行为。
让我们逐步了解上面的代码以了解发生了什么,首先关注未缩进的行以及它们在脚本中的显示顺序。记住那个功能-或者
def
-块在被调用之前不会自己做任何事情。如果口译员自言自语地说:
-
打开xy.py作为“home”文件;调用它
“主要”
在
__姓名__
变量。
-
导入并打开文件
__name\uuuu=“ab.py”名称
.
-
哦,一个函数我会记住的。
-
好的,功能
a()
;我刚学会打印'
ab文件中的一个函数
'.
-
文件结尾;返回
“主要”
!
-
哦,一个函数我会记住的。
-
另一个。
-
功能
x()
;好,打印'
外围任务:可能在其他项目中有用
'.
-
这是什么?一个
if
陈述嗯,条件已经满足了(变量
__姓名__
已设置为
“主要”
),所以我将进入
main()
功能和打印
主要功能:动作在这里
'.
最后两行的意思是:“如果这是
“主要”
或者“home”脚本,执行
主()
". 所以你会看到
def main():
阻塞top,它包含脚本功能的主要流程。
为什么要这么做?
还记得我之前说过的关于导入语句的话吗?当您导入一个模块时,它不仅仅是“识别”它并等待进一步的指令——它实际上运行脚本中包含的所有可执行操作。所以,把你剧本的精华放进
主()
函数有效地隔离它,使其处于隔离状态,以便在被另一个脚本导入时不会立即运行。
同样,也会有例外,但通常的做法是
主()
通常不会被外部调用所以你可能还想知道一件事:如果我们不打电话
主()
,为什么我们要调用脚本?这是因为许多人用独立的函数构造他们的脚本,这些函数是独立于文件中的其他代码运行的他们后来在剧本的其他地方被调用这让我想到:
但如果没有密码的话
是的,没错这些独立的功能
可以
从不包含在
主()
功能。如果你习惯了(就像我一样,在我早期的编程学习阶段)构建符合你需要的内联脚本,并且如果你再次需要这个操作,你会再次尝试找出答案。。。好吧,你不习惯代码的这种内部结构,因为构建起来更复杂,阅读起来也没那么直观。
但这是一个脚本,可能无法在外部调用它的函数,因为如果它这样做了,它将立即开始计算和分配变量如果你试图重新使用一个函数,那么你的新脚本和旧脚本的关系非常密切,可能会有冲突的变量。
在分离独立的函数时,通过将它们调用到另一个脚本中,可以获得重用以前工作的能力。例如,“example.py”可以导入“xy.py”并调用
x()
,使用“xy.py”中的“x”函数(可能是将给定文本字符串的第三个单词大写;从数字列表中创建NumPy数组并将其平方;或者取消三维曲面的格式可能性是无限的。)
(作为旁白,
this question
包含一个@kindall的答案,它最终帮助我理解了为什么,而不是如何。不幸的是它被标记为
this one
,我认为这是个错误。)