1.2.1 if__name__=='__main__'

相信读者在学习Python基础语法的时候,在程序最后经常会遇到这句话,这里简单解释下它的意义。总地来说,这句代码的作用是既能保证当前的.py文件直接运行,也能保证其可以作为模块被其他.py文件导入。下面通过几个例子帮助读者加深理解。

首先,创建一个.py文件,设置文件名,这里为Hello.py。编辑文件,运行下面这句代码。

    print(__name__)

其输出如下。

    __main__

这说明,__name__本身是一个变量,但它不是一般的变量。实际上,它是在程序执行前就创建并赋值的,而赋值的机制是这里的关键。在当前程序被当作主程序被执行的时候,__name__自动被赋值为固定的字符串__main__;当它作为模块被其他文件调用的时候,自动被赋值为模块所在的文件名。

基于上述对__name__的理解,新建name_main.py文件,写入下面这段代码。

    def printHello():
        print("Hello World! ")
        print(__name__)
    if __name__ ==  '__main__':
        printHello()

其输出如下。

    Hello World!
    __main__

因为name_main.py文件是作为主程序来运行的,所以__name__此处被赋值为__main__。此时程序的逻辑很清楚:定义一个函数,然后判断语句,最后判断后通过执行函数。

细心的读者可能已经发现,即使不要判断语句,程序一样可以运行。例如使用以下代码,程序还是可以正常运行的。

    def printHello():
        print("Hello World! ")
        print(__name__)

    printHello()

可见这句代码的作用是,既能保证当前的.py文件直接运行,也能保证其可以作为模块被其他.py文件导入。所以它也可以在当前文件被当作一个模块调入的时候发挥关键的作用。

假设name_main.py就用这种不带if判断语句的写法,新建name_main1.py,按照如下的方式将name_main.py作为模块调入。

    from name_main import printHello
    printHello()

运行name_main1.py文件,想想看,输出会是什么?可能会和大家想的有些出入。

    Hello World!
    name_main
    Hello World!
    name_main

首先,可以看到name_main.py在被作为模块调入的时候,对应的__name__被赋值为对应的文件名,这一点是在意料之中的。虽然只运行了name_main1.py文件,但是可以明显看到函数被执行了两次,这就是关键所在。这是因为,不带if判断语句的name_main.py文件在作为模块被引入时,printHello函数已经自动执行了一次,之后在name_main1.py被主动调用时执行了一次,一共执行两次。

那么,此句代码的作用已经十分清楚了,它保证模块文件的函数既能在模块文件单独执行,又能保证它被其他.py文件调入时,相应的函数不被重复执行。

回到本例,编辑name_main.py,如下所示。

    def printHello():
        print("Hello World! ")
        print(__name__)
    if __name__ ==  '__main_ _':
        printHello()

运行输出如下。

    Hello World!
    __main__

编辑name_main1.py,如下所示。

    from name_main import printHello
    printHello()

运行输出如下。

    Hello World!
    name_main

这样既能单独运行name_main.py进行printHello函数的调试等操作,也能保证name_main1.py可以正常使用printHello函数。