zoukankan      html  css  js  c++  java
  • if __name__ == '__main__'详解

    原文:https://www.cnblogs.com/chenhuabin/p/10118199.html

     

     

    1 引言

      在Python当中,如果代码写得规范一些,通常会写上一句“if __name__==’__main__:”作为程序的入口,但似乎没有这么一句代码,程序也能正常运行。这句代码多余吗?原理又在哪里?本篇博文对此进行总结说明。

    2 程序入口

             学过Java、C、C++的程序员应该都知道,每次开启一个程序,都必须写一个主函数作为程序的入口,也就是我们常说的main函数。如下所示, main()就是Java中的一个main函数。

    复制代码
    public class HelloWorld {
    
        public static void main(String[] args) {
    
            System.out.println("HelloWorld");
    
        }
    
    }    
    复制代码

      与Java、C、C++等几种语言不同的是,Python是一种解释型脚本语言,在执行之前不同要将所有代码先编译成中间代码,Python程序运行时是从模块顶行开始,逐行进行翻译执行,所以,最顶层(没有被缩进)的代码都会被执行,所以Python中并不需要一个统一的main()作为程序的入口。在某种意义上讲,“if __name__==’__main__:”也像是一个标志,象征着Java等语言中的程序主入口,告诉其他程序员,代码入口在此——这是“if __name__==’__main__:”这条代码的意义之一。

    3 模块导入

             我们知道,当我们把模块A中的代码在模块B中进行import A时,只要B模块代码运行到该import语句,模块A的代码会被执行。

      模块A:

    复制代码
    # 模块A
    
    a = 100
    
    print('你好,我是模块A……')
    
    print(a)
    复制代码

      模块B:

    复制代码
    # 模块B
    
    from package01 import A
    
    b = 200
    
    print('你好,我是模块B……')
    
    print(b)
    复制代码

      运行模块B时,输出结果如下:

      你好,我是模块A……

      100

      你好,我是模块B……

      200

      如果在模块A中,我们有部分的代码不想在被导入到B时直接被运行,但在直接运行A时可直接运行,那该怎么做呢?那就可以用到“if __name__==’__main__:”这行代码了,我们队上面用到的A模块代码进行修改:

      A模块代码修改为:

    复制代码
    # 模块A
    
    a = 100
    
    print('你好,我是模块A……')
    
    if __name__=='__main__':
    
        print(a)
    复制代码

      B模块不做修改,直接执行B模块,输出结果如下:

      你好,我是模块A……

      你好,我是模块B……

      200

      看到了吗,A模块中的a的值就没有再被输出了。所以,当你要导入某个模块,但又不想该模块的部分代码被直接执行,那就可以这一部分代码放在“if __name__=='__main__':”内部。

    4 “__name__”与“__main__”

             看到现在也许心中还是疑惑,为什么会这样,那么现在我们来说一说“if __name__=='__main__':”的原理。

             “__name__”是Python的内置变量,用于指代当前模块。我们修改上面用到的A模块和B模块,在模块中分别输出模块的名称:

      模块A:

    复制代码
    # 模块A
    
    print('你好,我是模块A……')
    
    print('模块A中__name__的值:{}'.format(__name__))
    
    print('-------------------------')
    复制代码

      模块B:

    复制代码
    # 模块B
    
    from package01 import A
    
    print('你好,我是模块B……')
    
    print('模块B中__name__的值:{}'.format(__name__))
    复制代码

      执行A模块时,输出结果:

      你好,我是模块A……

      模块A中__name__的值:__main__

      -------------------------

      执行B模块时,输出结果:

      你好,我是模块A……

      模块A中__name__的值:package01.A

      -------------------------

      你好,我是模块B……

      模块B中__name__的值:__main__

      发现神奇之处了吗?当哪个模块被直接执行时,该模块“__name__”的值就是“__main__”,当被导入另一模块时,“__name__”的值就是模块的真实名称。用一个类比来解释一下:记得小时候要轮流打算教室,轮到自己的时候(模块被直接执行的时候),我们会说今天是“我”(__main__)值日,称呼其他人时,我们就会直接喊他们的名字。所以,“__main__”就相当于当事人,或者说第一人称的“我”。

      所以,当运行“if __name__=='__main__':”语句时,如果当前模块时被直接执行,__name__的值就是__main__,条件判断的结果为True,“if __name__=='__main__':”下面的代码块就会被执行。

    5 总结

             “if __name__=='__main__':”语句的用处与原理大概也讲清楚了,如果没说明白,或者是我没理解到位,请给我留言。另外多说一句,“if __name__=='__main__':”很多时候看似无用,但是,出于代码的规范性,还是有必要的。

    本博客为记录本人遇到问题时所找到的解决方案,且均经过本人亲测可用,如有侵权请联系添加来源或删除文章,谢谢。
  • 相关阅读:
    POJ 1811 Prime Test 素性测试 分解素因子
    sysbench的安装与使用
    电脑中已有VS2005和VS2010安装.NET3.5失败的解决方案
    I.MX6 show battery states in commandLine
    RPi 2B Raspbian system install
    I.MX6 bq27441 driver porting
    I.MX6 隐藏电池图标
    I.MX6 Power off register hacking
    I.MX6 Goodix GT9xx touchscreen driver porting
    busybox filesystem httpd php-5.5.31 sqlite3 webserver
  • 原文地址:https://www.cnblogs.com/heymonkey/p/11759749.html
Copyright © 2011-2022 走看看