if __name__ == ‘__main__’:

if __name__ == '__main__':

# hello.py

def hello():
    print("this is hello function")

if __name__ == '__main__':
    hello()

  在Python的代码中,我们经常看到以上这样的写法:首先我们声明一个函数hello(),接着是if条件判断,判断变量__name__的值是否为__main__。如果当前文件(hello.py)是主模块,则调用函数hello(),如果当前文件是被其他文件import包含,则当前文件就不是主模块,条件判断为false,不调用函数hello()
  那么,这个__name__是怎么来的,同时,什么是主模块呢?我们一一讨论一下。

模块

在Python中,一个.py的文件就是一个模块。当前运行的.py文件就是主模块

  那么,Python程序中的模块那么多,该如何维护呢?CPython中定义了一个结构体PyMudoleObject,其中有一个字典,用来维护该模块下的变量、函数、类等等符号。同时,CPython会在这个字典里面存放两个变量,这两个变量分别为__name____doc__;用来表示该module的名字和文档说明

typedef struct {
    PyObject_HEAD
    PyObject *md_dict;
} PyModuleObject;

  cpython在运行程序前,进行初始化工作的时候,就会生成一个__main__模块,该模块其实就是当前运行的Python文件自身。在这个__main__模块中,有一个属性,正是__name__,而它的值正是__main__
  那么,这个__main__模块在哪里呢?默认情况下,该模块并没有被引入到globals名字空间中。但是,CPython会在线程中维护一个modules,其中存放了所有被引入的模块,而我们可以通过sys模块访问到modules模块:

>>>import sys
>>>dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'sys']
>>>sys.modules['__main__']
<module '__main__' (built-in)>

  现在,我们将__main__引入进来,可以看到__name____main__.__name__指向了同一个字符串对象:

>>>import __main__
>>>__main__.__name__
'__main__'
>>>__name__
'__main__'
>>>id(__name__)
8701856
>>>id(__main__.__name__)
8701856

  但是,还有一个问题,就是__name__起初是在modules对应的字典中,那么,为什么在Python代码中,我们可以直接使用呢?
  答案就是cpython在globals名字空间中创建了一个属性__name__,该属性的值正是modules字典中维护的__name__的值。

  如果上面hello.py被其他模块引入,该函数就不会执行了。因为此时候在hello.py中输出__name__,它的值为hello

# test.py

import hello    # 引入hello.py

#没有任何输出