Python程序设计教程(第2版)
上QQ阅读APP看书,第一时间看更新

1.8 模块的__name__属性

每个模块都有一个__name__属性(注意__name__下画线),该属性保存当前模块执行过程中的名称。当一个程序模块独立运行时,该__name__属性自动被赋予值为__main__的字符串。如果一个程序模块被其他程序通过import导入使用,则其__name__属性自动被赋予值为模块名(文件名)的字符串。

【例1-4】 编写一个函数printName(),打印当前模块的__name__属性值,主程序调用执行该函数,程序保存为nametest.py。

函数的设计方法将在第6章中详细阐述。这里先给出实现的源代码:

直接执行该程序的运行结果为:

因为nametest.py程序作为一个独立模块运行,因此其__name__值为字符串"__main__"。

【例1-5】 编写一个程序,调用例1-4中nametest.py中的printName()函数,程序保存为nametestimport.py。为了简化阐述,程序与nametest.py保存到同一个目录下。

程序源代码如下:

程序执行结果如下:

因为nametest.py作为一个模块被nametestimport.py程序通过import引用,因此其__name__属性值为模块的名称nametest。

为什么执行结果的字符串重复打印两次呢?因为被import的nametest.py中,有主程序调用printName()函数的语句,因此在import nametest的时候执行了一次printName(),输出了“当前__name__值为:nametest”。nametestimport.py中接着通过语句nametest.printName()调用了printName()函数,再一次输出“当前__name__值为:nametest”。

因此,如果一个程序模块可能被其他程序通过import引用,最好在主程序开始之前添加“if__name__=='__main__':”的条件语句,这样该模块在被其他程序通过import引用时,因为其__name__属性的值不为“__main__”,主程序不会执行。

修改例1-4的程序如下:

直接运行该程序的执行结果与原来一样。

相应地,将例1-5的程序修改如下:

此时,程序的运行结果为:

因为,当nametest2.py被nametestimport2.py引用时,nametest2中的__name__属性值为'__nametest2__',此时nametest2中的主程序if后面的条件为假,因此printName()没有被调用。直到nametestimport2.py执行nametest2.printName()函数时,才打印一次。

如果进一步考虑到例1-5中的程序将来可能被其他程序通过import引用,也可以将其进一步修改为: