博客是我工作的好帮手,遇到困难就来博客找资料
分类: 系统运维
2017-02-16 14:28:43
很多新手刚开始学习python的时候经常会看到python 中__name__ = \'__main__\' 这样的代码,可能很多新手一开始学习的时候都比较疑惑,python 中__name__ = '__main__' 的作用,到底干嘛的?
有句话经典的概括了这段代码的意义:
“Make a script both importable and executable”
意思就是说让你写的脚本模块既可以导入到别的模块中用,另外该模块自己也可执行。
这句话,可能一开始听的还不是很懂。下面举例说明:
先写一个模块:
#module.py
def main():
print "we are in %s"%__name__
if __name__ == '__main__':
main()
这个函数定义了一个main函数,我们执行一下该py文件发现结果是打印出”we are in __main__“,
说明我们的if语句中的内容被执行了,调用了main():
但是如果我们从另我一个模块导入该模块,并调用一次main()函数会是怎样的结果呢?
#anothermodle.py
from module import main
main()
其执行的结果是:we are in module
但是没有显示”we are in __main__“,也就是说模块__name__ = '__main__' 下面的函数没有执行。
这样既可以让“模块”文件运行,也可以被其他模块引入,而且不会执行函数2次。这才是关键。
总结一下:
如果我们是直接执行某个.py文件的时候,该文件中那么”__name__ == '__main__'“是True,
但是我们如果从另外一个.py文件通过import导入该文件的时候,这时__name__的值就是我们这个py文件的名字而不是__main__。
这个功能还有一个用处:调试代码的时候,在”if __name__ == '__main__'“中加入一些我们的调试代码,我们可以让外部模块调用的时候不执行我们的调试代码,但是如果我们想排查问题的时候,直接执行该模块文件,调试代码能够正常运行!
1、这段代码的功能
一个python的文件有两种使用的方法,
第一是直接作为脚本执行,
第二是import到其他的python脚本中被调用(模块重用)执行。
因此if __name__ == 'main': 的作用就是控制这两种情况执行代码的过程,
在if __name__ == 'main': 下的代码只有在第一种情况下(即文件作为脚本直接执行)才会被执行,
而import到其他脚本中是不会被执行的。
举个例子,下面在test.py中写入如下代码:
print "I'm the first."
if __name__=="__main__":
print "I'm the second."
并直接执行test.py,结果如下图,可以成功print两行字符串。
即,if __name__=="__main__": 语句之前和之后的代码都被执行。
然后在同一文件夹新建名称为import_test.py的脚本,只输入如代码:
import test
执行import_test.py脚本,输出结果如下:
只输出了第一行字符串。即,if __name__=="__main__": 之前的语句被执行,之后的没有被执行。
2、运行的原理
每个python模块(python文件,也就是此处的test.py和import_test.py)都包含内置的变量__name__,当运行模块被执行的时候,__name__等于文件名(包含了后缀.py);如果import到其他模块中,则__name__等于模块名称(不包含后缀.py)。而“__main__”等于当前执行文件的名称(包含了后缀.py)。进而当模块被直接执行时,__name__ == 'main'结果为真。
同样举例说明,我们在test.py脚本的if __name__=="__main__":之前加入print __name__,即将__name__打印出来。文件内容和结果如下,
可以看出,此时变量__name__的值为"__main__";
再执行import_test.py,模块内容和执行结果如下:
此时,test.py中的__name__变量值为test,不满足__name__=="__main__"的条件,因此,无法执行其后的代码。
Python脚本和模块都是一个以.py结束的文件,那程序是如何判断一个.py文件是作为脚本还是模块呢?
关键是一个名为__name__的变量,如果它的值是__main__,则不能作为模块,只能作为脚本直接运行。
所以在很多脚本的最后都有一段类似下面的语句,限制只能以脚本方式运行,不作为模块:
if __name__ == '__main__':
main()
def test():
print "test is running"
if __name__ == "__main__":#自运行时调用该程序块
print "test main is working"
if __name__ == "test":#import时调用该程序块
print "test is invoked"
自执行效果如图:
import执行效果如图:
执行test()方法效果如图:
通过这个例子,python应用模块的自程序都放在 if __name__ == "__main__" 条件块下是多么方便。
#hello.py
def sayHello():
str="hello"
print(str);
if __name__ == "__main__":
print ('This is main of module "hello.py"')
sayHello()
python作为一种脚本语言,我们用python写的各个module都可以包含以上那么一个累死c中的main函数,只不过python中的这种__main__与c中有一些区别,主要体现在:
1、当单独执行该module时,比如单独执行以上hello.py: python hello.py,则输出
This is main of module "hello.py"
hello
可以理解为"if __name__=="__main__":" 这一句与c中的main()函数所表述的是一致的,即作为入口;
2、 当该module被其它module 引入使用时,其中的"if __name__=="__main__":"所表示的Block不会被
执行,这是因为此时module被其它module引用时,其__name__的 值将发生变化,__name__的值将会是
module的名字。比如在python shell中import hello后,查看hello.__name__:
>>> import hello
>>> hello.__name__
'hello'
>>>
3、 因此,在python中,当一个module作为整体被执行时,moduel.__name__的值将是"__main__";
而当一个 module被其它module引用时,module.__name__将是module自己的名字,
当然一个module被其它module引用时,其 本身并不需要一个可执行的入口main了。
可以说python中的这种用法很灵活啊。