关于 if __name__ == '__main__'的正确理解

先看下面这一段话:

所有的 Python 模块(也就是一个py文件)都是对象并且有几个有用的属性,你可以使用这些属性方便地测试你所书写的模块。

所有的模块都有一个内置属性 __name__。一个模块的 __name__ 的值要看如何应用该模块。如果 import该模块, 那么 __name__的值通常为模块的文件名, 不带路径或者文件扩展名。如果像一个标准的程序一样直接运行模块, 在这种情况下 __name__的值将是一个特别的缺省值:__main__。

看以下例子:

hello.py

def helloWorld():
    print "hello world"
a.py
from hello import helloWorld
if __name__ == '__main__':
    helloWorld()
将hello.py和a.py放在同一个目录下,在该目录下打开终端,在终端输入
python a.py
输入并执行后,python编译器会逐行编译a.py中的语句,首先就是from hello import helloWorld。hello.py因为是引入的,所以,它的模块名就等于 hello ,即 __name__ == 'hello' ,然而a.py文件因为是直接执行,所以,a.py的__name__就等于 '__main__' ,即 __name__ == '__main__',这样,等编译器到达下面的if 判断时,就会执行 helloWorld()这个方法了。也就是说 __name__ 的值是在执行了 python ××.py 之后才确定的,这个值应该是存在内存中,存在pyCodeObject中。

顺序如下:
  1. python xxx.py
  2. xxx.py 的 __name__ 属性被赋值为 "__main__"
  3. if __name__ =='__main__'判断下,如果满足则继续往下执行.
题外话:当python a.py执行结束后,会发现当前目录下多了一个hello.pyc文件,这是因为python程序执行的时候,是先编译,后解释,即先把py文件编译成pyCodeObject对象,这个对象是python编译器真正编译成的结果,这个对象存在内存中,然后再由解释器执行。pyc文件是pyCodeObject持久化的结果。
但是为什么只有import的那些文件会生成pyc文件呢,这是从为了让程序模块化、方便重用的角度来考虑的,这样的话,执行主程序的时候,只需要执行相应模块的pyc文件就可以了,可以提升文件执行速度。