进度一:
前几天,我学习python时,编写简单的代码,一般是这样的:
pi.py
PI=3.14
print("this is out")
def main():
print("PI=",end='')
print(PI)
main()
我以为在代码最后调用main()函数,表示从主函数开始运行。但后来,但是看了这个代码,我惊了...在函数外部居然也可以使用语句,也就是说,python作为一门解释型语言,并不是从主函数开始的,它是通过缩进判断,并且在载入时自动执行无缩进代码。注意这里的“无缩进”!函数也是无缩进的,但函数是肯定必须得是被调用时才 会被执行。
进度二:
再看下个例子:
pi.py
PI=3.14
print("this is out")
def lala():
print("lala")
#lala() 这个位置调用也可以 ,看下面解释
def main():
print("PI=",end='')
print(PI)
lala()
main()
仔细看上面的输出,按着我所讲的“从无缩进的代码开始运行”,从第一行开始扫描,运行无缩进代码,依次是:
print("this is out")-->lala()-->main(),不要管函数,函数必须被调用才会被执行。所以我是不是可以认为,python的运行并不是自动运行main()函数,它没有所谓的主函数,也没有所谓的入口,它的运行取决于用户想让他运行哪个。我想让他运行lala()函数,我就在代码的最后(也可以不是在最后,任何位置)顶格写这个函数名字,python就会自动扫描到这里,运行这个函数。
进度三:
然鹅,我又在网上看到了这种调用:
if __name__ == '__main__':
main()
这是啥玩意,第一反应,我在学java是基本没见过下划线,这好几个线让我很陌生。
注意:这里都是双下划线,我起初都看错了,我说咋打印不出来呢。看下面代码:
PI=3.14
print("this is out")
def main():
print("PI=",end='')
print(PI)
print(type(__name__))
print(__name__)
main()
通过上述代码的输出,可以看出 __name__是一个内置变量,属于字符串类型,它的值是__main__。好,暂且就这样认为。
进度四:
现在,我要计算一个圆的面积。有两个文件,分别是pi.py和circle.py。
pi.py :用来打印圆周率
PI=3.14
def main():
print("PI =",3.14)
main()
circle.py:用来计算圆的面积
def area(r):
return 3.14*r*r
def main():
r = 2
s = area(r)
print('area:',s)
main()
现在,我想用通过导入pi.py作为circle.py模块 。就是说我想使用pi.py里面的PI的值。这里需要使用import导入。
from pi import PI
def area(r):
return PI*r*r
def main():
r = 2
s = area(r)
print('area:',s)
main()
看上面的代码,我们的预想输出是 area:12.56 但是
发现他同样执行了pi.py模块中的main()函数即输出了PI的值。这个使用上面我说的“从第一行顺次扫描执行无缩进代码”可以解释。也就是对于circle.py文件来说,从第一行开始,包括import导入的模块,都要扫描。但是,我们并不关心原模块自己内部的使用情况,我们只是想借用下模块中的一些函数或变量,不想让你原来模块的内容干涉(这里它执行了PI模块,输出了)。因此就可以使用__name__内置变量进行判断了。
在上面我们说__name__的值为__main__,其实不然。当你直接运行文件时,这个文件的__name__是__main__;但是
当你以模块导入供其他文件使用时,此模块的__name__的值是模块的名字(这里是pi)。这时我们就可以在模块中写个if语句放在末尾进行判断
if __name__ =="__main__":
main()
上述意思就是如果当前文件是直接被调用,那么执行main()函数;如果是作为模块被其他文件调用(if判断是Flase),则不执行。
因此,上述两个文件可以修改为:
pi.py
PI=3.14
print(__name__)
#直接运行时,输出__main__
#作为模块被调用时,输出模块的名称 pi
def main():
print("PI =",3.14)
if __name__ == "__main__":
main()
circle.py
from pi import PI
def area(r):
return PI*r*r
def main():
r = 2
s = area(r)
print('area:',s)
if __name__ == "__main__":
main()
这样就改变了我们当初运行代码的方式(仅仅在尾部写main()),通过这种特性,为测试驱动开发提供了极好的支持,我们可以在每个模块中写上测试代码,这些测试代码仅当此模块被直接调用时执行;当它作为某个功能的整体被调用时,不运行测试代码,代码和测试完美的结合在一起。
总结:
- python 代码的执行不依赖于 main()函数。在C/C++/Java中,main是程序执行的起点;Python中,使用缩进对齐组织代码的执行,所有没有缩进的代码(函数除外和类类除外),都会在载入时自动执行。
- 每个文件(模块)都可以任意写一些没有缩进的代码,并且在载入时自动执行,为了区分主执行文件还是被调用的文件,Python引入了一个变量__name__,当文件是被调用时,__name__的值为模块名,当文件被执行时,__name__为'__main__'。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)