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

    __name__ == '__main__'到底是什么意思
    相信许多人初学 Python 时,常会在例子程序中看到如下语句:

    1 if __name__ == '__main__':
    2 foo() # 或其他语句

    第 1 行的__name__ == '__main__'到底是什么意思呢?

    首先,如果你永远都只执行一个 xxx.py,而不去 import它的话,那你完全不需要了解这是什么。例如你写了一个程序,文件名叫 hello.py

    1 print("====this is hello.py====")
    2 def foo():
    3 print("hello")
    4 print("call foo() which is defined here") 
    5 foo()
    6 print("====this is hello.py END ====")

    然后你总是直接执行它,就像这样

    1 $ python3 hello.py 
    2 ====this is hello.py====
    3 call foo() which is defined here
    4 hello
    5 ====this is hello.py END ====

    这完全没有问题。

    但是,当别人想引用你的foo()函数时,就有问题了。

    例如别人写了一个文件,名字是 world.py

    1 # world.py
    2 print("====this is world.py====")
    3 from hello import foo
    4 
    5 print("call foo() which is defined in other file")
    6 foo()
    7 print("====this is world.py END ====")

    运行结果如下:

    1 $ python3 world.py 
    2 ====this is world.py====
    3 ====this is hello.py====
    4 call foo() which is defined here
    5 hello
    6 ====this is hello.py END ====
    7 call foo() which is defined in other file
    8 hello
    9 ====this is world.py END ====

    可以看到,解释器是逐行解释源码的,当执行到源码的第 3 行时,也就是 hello.py 被引用时,hello.py 的每一行都会被解释器读取并执行,执行效果就是结果中的3~6行,然后解释器执行源码的5~7行。

    如果你不想要结果中的3~6行,该怎么做呢?

    Python 解释器执行代码时,有一些内建、隐含的变量,__name__就是其中之一,其意义是“模块名称”。

    如果该模块是被引用,那么__name__的值会是此模块的名称;如果该模块是直接被执行,那么__name__的值是__main__。

    或许你还不明白,那我们来做个实验。

    1 # hello.py
    2 print("====this is hello.py====")
    3 print(__name__)
    4 def foo():
    5 print("Ha")
    6 print("call foo() which is defined here") 
    7 foo()
    8 print("====this is hello.py END ====")

    请注意上面第3行

    1 # world.py
    2 print("====this is world.py====")
    3 print(__name__)
    4 from hello import foo
    5 print("call foo() which is defined in other file")
    6 foo()
    7 print("====this is world.py END ====")

    同样,请注意上面第3行

    我们看一下运行结果。

    对于第一个:

    1 $ python3 hello.py 
    2 ====this is hello.py====
    3 __main__
    4 call foo() which is defined here
    5 Ha
    6 ====this is hello.py END ====

    从结果的第3行可以看出,对于直接运行的模块,其模块名是 __main__

    对于第二个:

     1 $ python3 world.py
     2 ====this is world.py====
     3 __main__ # 因为 world.py 被直接执行,所以这里的值是 __main__
     4 ====this is hello.py====
     5 hello # 因为 hello.py 被引用,所以这里的值是 hello
     6 call foo() which is defined here
     7 Ha
     8 ====this is hello.py END ====
     9 call foo() which is defined in other file
    10 Ha
    11 ====this is world.py END ====

    注意到第5行了吗?这里的“hello”正是 hello.py 被引用时的模块名称。

    由此可见,__name__的值在模块被直接执行时与被引用时是不同的。

    回到上面的问题:当一个模块被引用时,如何不执行该模块的语句?答案就是靠判断__name__是否等于 __main__。当一个模块被直接执行时,其__name__必然等于__main__;当一个模块被引用时,其__name__必然等于文件名(不含.py);

    总结
    之所以常看见这样的写法,是因为该程序可能有“单独执行”(例如执行一些单元测试)与“被引用”两种情况,鉴于这两种情况中__name__的值是不同的:当一个模块被直接执行时,其__name__必然等于__main__;当一个模块被引用时,其__name__必然等于文件名(不含.py)。所以利用判断__name__ == '__main__'的真假就可以将这两种情况区分出来。

  • 相关阅读:
    对MVC模型的自悟,详尽解释,为了更多非计算机人员可以理解
    openSUSE leap 42.3 实现有线 无线同时用
    Fedora27 源配置
    Ubuntu16.04添加HP Laserjet Pro M128fn打印机和驱动
    openSUSE leap 42.3 添加HP Laserjet Pro M128fn打印机和驱动
    OpenSUSE Leap 42.3下通过Firefox Opera Chromium浏览器直接执行java应用程序(打开java jnlp文件)实现在服务器远程虚拟控制台完成远程管理的方法
    OpenSUSE Leap 42.3 安装java(Oracle jre)
    linux下支持托盘的邮件客户端Sylpheed
    Ubuntu下通过Firefox Opera Chromium浏览器直接执行java应用程序(打开java jnlp文件)实现在服务器远程虚拟控制台完成远程管理的方法
    Firefox 浏览器添加Linux jre插件
  • 原文地址:https://www.cnblogs.com/hly97/p/13172949.html
Copyright © 2011-2022 走看看