背景

在写Python代码和看Python代码时,我们常常可以看到这样的代码:

?
1
2
3
4
5
def main():
    ......
if __name__ == "__main__":
    main();

其中的函数名main,也可以是其他任意的,你所设置的名字。

这里,就出现了,我们此处所要解释的

__name__和__main__

__name__和__main的含义

其实,对于Python中的这类问题,根据我之前的:

【整理】如何学习Python + 如何有效利用Python有关的网络资源 + 如何利用Python自带手册(Python Manual)

中的介绍,最好的学习的方法,其实就是去看官网文档:

__name__的含义

__name__ is set to name of module

另外还有几处的解释:

Modules…

Predefined (writable) attributes: __name__ is the module’s name;

… Classes…

Special attributes: __name__ is the class name;

从这几处的解释,我们很容易理解其基本的意思:

__name__,

如果是放在Modules模块中,就表示是模块的名字;

如果是放在Classs类中,就表示类的名字;

__main__的含义

同理,先去官网文档中看对应的解释:

__main__ be inited

对应的其他几处的解释是:

4.1. Naming and binding

The namespace for a module is automatically created the first time a module is imported. The main module for a script is always called __main__.

8.1. Complete Python programs

While a language specification need not prescribe how the language interpreter is invoked, it is useful to have a notion of a complete Python program. A complete Python program is executed in a minimally initialized environment: all built-in and standard modules are available, but none have been initialized, except for sys (various system services), __builtin__ (built-in functions, exceptions and None) and __main__. The latter is used to provide the local and global namespace for execution of the complete program.

….

The interpreter may also be invoked in interactive mode; in this case, it does not read and execute a complete program but reads and executes one statement (possibly compound) at a time. The initial environment is identical to that of a complete program; each statement is executed in the namespace of __main__.

void Py_Initialize()

Initialize the Python interpreter. In an application embedding Python, this should be called before using any other Python/C API functions; with the exception of Py_SetProgramName(), PyEval_InitThreads(), PyEval_ReleaseLock(), and PyEval_AcquireLock(). This initializes the table of loaded modules (sys.modules), and creates the fundamental modules __builtin__, __main__ and sys.

说实话,对于__main__,上述的解释,并不是那么容易看的懂。

其实要看懂上面的解释,我们首先要知道的一些前提是:

python代码,是可以直接一行行写出来,然后去运行,是可以的。但是这只是针对我们的小程序来说的。

更多的Python代码,是写成更加通用的,可以被调用的,可以重复利用的,模块的形式;

所以都是写在对应的函数里面的。

而作为模块,就是上面的解释中的:

The namespace for a module is automatically created the first time a module is imported. The main module for a script is always called __main__.

模块第一次被导出(import)后,系统会自动为其创建一个域名空间(namespace);

(模块,都是有自己的名字的)此处的脚本的主模块的名字,始终都叫做__main__。

用代码来演示__name__和__main__的含义和用法

示例1

文字解释,还是很容易糊涂的,下面就来借用一个这里:

What is ‘if __name__ == “__main__”‘ for?

的代码来详细解释一下。

作为普通的代码,我们是可以这么写的:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
【整理】Python中的__name__和__main__含义详解
http://www.crifan.com/python_detailed_explain_about___name___and___main__
Version:    2012-11-17
Author:     Crifan
Contact:    http://www.crifan.com/contact_me/
"""
def square(x):
    return x * x
print "test: square(42) ==",square(42);

对应的,运行结果也是很正常的:

?
1
2
E:\Dev_Root\python\__name___and___main__>__name___and___main__.py
test: square(42) == 1764

但是呢,往往我们所见到的,和我们以后自己也会遇到的,自己写的,有条理的,可复用的做法,那肯定是

那对应的square等函数,专门放到一个文件中,然后被别人调用,此时,就是这样的:

对应的模块文件是mymath.py,里面有我们实现的函数square:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
【整理】Python中的__name__和__main__含义详解
http://www.crifan.com/python_detailed_explain_about___name___and___main__
Version:    2012-11-17
Author:     Crifan
Contact:    http://www.crifan.com/contact_me/
"""
def square(x):
    return x * x
print "test: square(42) ==",square(42);

然后别的python文件__name___and___main__.py中,导入此mymath模块,然后使用其square函数:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
【整理】Python中的__name__和__main__含义详解
http://www.crifan.com/python_detailed_explain_about___name___and___main__
Version:    2012-11-17
Author:     Crifan
Contact:    http://www.crifan.com/contact_me/
"""
import mymath;
print "In caller, test for mymath: square(12)=",mymath.square(12);

然后运行结果是:

?
1
2
3
E:\Dev_Root\python\__name___and___main__>__name___and___main__.py
test: square(42) == 1764
In caller, test for mymath: square(12)= 144

此处,我们看到了,也同时出现了,原本用于mymath.py中去测试square函数的打印结果:

test: square(42) == 1764

而这样的内容,很明显,是作为我模块的调用者,不希望看到的。也不关心的。

此时,我们所希望的是:

作为模块mymath.py本身,希望有自己的相关的调试的代码,用于调试自己模块函数,演示如何使用等等代码;

但是又不希望在被别的,本模块的调用者,所执行到,所看到;

此时,就可以用上述的__main__来实现了:

把mymath.py改为:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
【整理】Python中的__name__和__main__含义详解
http://www.crifan.com/python_detailed_explain_about___name___and___main__
Version:    2012-11-17
Author:     Crifan
Contact:    http://www.crifan.com/contact_me/
"""
def square(x):
    return x * x
if __name__ == "__main__":
    print "test: square(42) ==",square(42);

此时:

1. 作为mymath.py本身,自己运行时,可以运行到此处的代码,调试,验证自己的函数square执行的是否正确:

?
1
2
E:\Dev_Root\python\__name___and___main__>mymath.py
test: square(42) == 1764

2.同时,作为mymath.py的调用者__name___and___main__.py,在import mymath的时候,也不会看到对应的代码执行的结果了:

?
1
2
E:\Dev_Root\python\__name___and___main__>__name___and___main__.py
In caller, test for mymath: square(12)= 144

其中的__main__,就是:

作为模块mymath.py本身:

  • 作为脚本自己去运行的话,对应的模块名,就是上面所解释的,始终叫做__main__

    • 关于这点,上述代码已经验证过了。因为mymath.py中的__name__,就是对应的,内置的变量,通过判断,的确是__main__,然后才会去执行到对应的模块的测试代码的。
    • 如果被当做一个模块被别人调用的时候,对应的模块mymath.py的模块名,就是mymath;

      • 关于这点,我们可以来验证一下,把__name___and___main__.py改为:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
【整理】Python中的__name__和__main__含义详解
http://www.crifan.com/python_detailed_explain_about___name___and___main__
Version:    2012-11-17
Author:     Crifan
Contact:    http://www.crifan.com/contact_me/
"""
import mymath;
print "In caller, test for mymath: square(12)=",mymath.square(12);
print "As module be imported, mymath module name=",mymath.__name__;

      • 再去运行,就可以看到输出的结果是mymath了:
?
1
2
3
E:\Dev_Root\python\__name___and___main__>__name___and___main__.py
In caller, test for mymath: square(12)= 144
As module be imported, mymath module name= mymath

示例2

另外,这里:

A Byte of Python  – A module’s __name__

也有个例子,相对更加简洁,需要的可以参考一下。

摘录其代码如下:

?
1
2
3
4
5
6
7
#!/usr/bin/python
# Filename: using_name.py
if __name__ == '__main__':
    print 'This program is being run by itself'
else:
    print 'I am being imported from another module'

【总结】

__name__:表示模块,类等的名字;

__main__:模块,xxx.py文件本身:

  • 被直接执行时,对应的模块名就是__main__了

    • 可以在
    • if __name__ == “__main__”:
    • 中添加你自己想要的,用于测试模块,演示模块用法等代码。
  • 作为模块,被别的Python程序导入(import)时,模块名就是本身文件名xxx了。

【后记 2012-12-27】

后来又专门针对上述的

A Byte of Python  – A module’s __name__

的代码去测试了一下实际效果。

其中,此处由于我中间包含了中文,所以必须添加对应的coding声明,否则,是会出现错误:

D:\tmp\tmp_dev_root\python\tutorial_summary\__name___and___main__>name_and_main.py
File “D:\tmp\tmp_dev_root\python\tutorial_summary\__name___and___main__\name_and_main.py”, line 6
SyntaxError: Non-ASCII character ‘\xe3’ in file D:\tmp\tmp_dev_root\python\tutorial_summary\__name___and___main__\name_and_main.py on line 7, but no encoding declared; see http://www.python.org/peps/p
ep-0263.html for details

添加了coding声明后,就正常了。

然后,最终的测试的代码是:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Filename: name_and_main.py
"""
Function:
【整理】Python中的__name__和__main__含义详解
http://www.crifan.com/python_detailed_explain_about___name___and___main__/
Author:     Crifan Li
Version:    2012-12-27
Contact:    admin at crifan dot com
"""
if __name__ == '__main__':
    print 'This program is being run by itself' #This program is being run by itself
else:
    print 'I am being imported from another module'

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/python
# -*- coding: utf-8 -*-
#Filename: caller_demo.py
"""
Function:
【整理】Python中的__name__和__main__含义详解
http://www.crifan.com/python_detailed_explain_about___name___and___main__/
Author:     Crifan Li
Version:    2012-12-27
Contact:    admin at crifan dot com
"""
import name_and_main;
print "Demo call name_and_main.py";
# I am being imported from another module
# demo call name_and_main.py

最终,测试出来的效果是:

?
1
2
3
4
5
6
D:\tmp\tmp_dev_root\python\tutorial_summary\__name___and___main__>caller_demo.py
I am being imported from another module
Demo call name_and_main.py
D:\tmp\tmp_dev_root\python\tutorial_summary\__name___and___main__>name_and_main.py
This program is being run by itself

总的来说,的确是我们所要的效果的,即:

python文件本身自己运行时,显示的是:This program is being run by itself

Python文件被别人import导入时,显示的是:I am being imported from another module

Python中的__name__和__main__含义详解相关推荐

  1. python中时间戳、字符串之间转换详解

    [转载]python中时间戳.字符串之间转换详解 (2013-04-30 17:36:07) 转载▼ 标签: 转载 原文地址:python中时间戳.字符串之间转换详解作者:doris0920 1)秒数 ...

  2. python argv 详解_对python中的argv和argc使用详解

    主要问题 为什么argv中第一个,即index=0的内容就是文件名? python中argc是用什么实现的? 概念解释 argc:argument counter,命令行参数个数 argv:argum ...

  3. python的raw_ input是什么意思-对python中raw_input()和input()的用法详解

    最近用到raw_input()和input()来实现即时输入,就顺便找了些资料来看,加上自己所用到的一些内容,整理如下: 1.raw_input() raw_input([prompt]) -> ...

  4. python中str和input_对python中raw_input()和input()的用法详解

    最近用到raw_input()和input()来实现即时输入,就顺便找了些资料来看,加上自己所用到的一些内容,整理如下: 1.raw_input() raw_input([prompt]) -> ...

  5. python3 isinstance用法_对python中assert、isinstance的用法详解

    1. assert 函数说明: Assert statements are a convenient way to insert debugging assertions into a program ...

  6. python中关于深拷贝和浅拷贝的详解

    python中关于深拷贝和浅拷贝的详解 概述 在python的语法中,有两种变量的拷贝方式 一种是深拷贝,一种是浅拷贝 我们先说深拷贝 语法 这里需要通过导入系统的copy模块中的deepcopy才可 ...

  7. python中zip的使用_浅谈Python中的zip()与*zip()函数详解

    前言 1.实验环境: Python 3.6: 2.示例代码地址:下载示例: 3.本文中元素是指列表.元组.字典等集合类数据类型中的下一级项目(可能是单个元素或嵌套列表). zip(*iterables ...

  8. python中验证码连通域分割的方法详解

    python中验证码连通域分割的方法详解 这篇文章主要给大家介绍了关于python中验证码连通域分割的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用python具有一定的参考学习价值,需 ...

  9. python gil 解除_详解Python中的GIL(全局解释器锁)详解及解决GIL的几种方案

    先看一道GIL面试题: 描述Python GIL的概念, 以及它对python多线程的影响?编写一个多线程抓取网页的程序,并阐明多线程抓取程序是否可比单线程性能有提升,并解释原因. GIL:又叫全局解 ...

最新文章

  1. C++代理类,句柄(智能指针)_C++沉思录笔记
  2. 散列基础知识总结(思维导图)
  3. java动画闪烁_优化Java动画编程中的显示效果
  4. powershell awk_谈谈 PowerShell
  5. 51 -leetcode 38 -字符串
  6. 如何在Windows7 x64 上安装oracle10g
  7. Bailian2911 受限完全平方数【暴力】
  8. android 手机 基站定位软件,安卓手机基站+GPS定位源码
  9. onhashchange事件--司徒正美
  10. 5750G GT540M显卡游戏蓝屏的终极解决方法!
  11. 还在使用手写笔记?又或者使用TXT、Word做笔记?NoNoNo,你需要一款合适的电子笔记!
  12. 什么是私有云、公有云、混合云?什么是云计算管理平台?
  13. 平板连接远程Linux,如何从Android平板电脑远程控制Ubuntu | MOS86
  14. JAVA计算机毕业设计晨光文具店进销存系统设计与开发Mybatis+源码+数据库+lw文档+系统+调试部署
  15. 小哈机器人发布新品_小哈教育机器人H2是什么时候正式发布的?
  16. 手撕迪杰斯特拉算法(Dijkstra)及代码(附图解)
  17. StringBuffer的理解
  18. 机器学习十大算法之三K-means
  19. java延迟1秒钟执行_如何让java延迟几秒钟?
  20. Moloch is not working 处理流程

热门文章

  1. R语言可视化dataframe数据、并自定义设置坐标轴各个标签使用不同的色彩
  2. python使用matplotlib可视化折线图、在可视化图像中同时绘制多条折线图
  3. R语言ggplot2可视化在图像中添加脚注信息(footnote)实战:自定义脚注信息的位置、对齐形式、图的脚注、整个网格的脚注
  4. Python使用matplotlib可视化自定义背景色实战:自定义可视化图像的背景色(Background Color)
  5. python使用fpdf的multi_cell API实现长文本写入的自动换行功能实战
  6. R语言apropos函数查找包含特定字符的函数、find函数查找函数所在的位置实战
  7. python使用imbalanced-learn的RepeatedEditedNearestNeighbours方法进行下采样处理数据不平衡问题
  8. NLP任务语义相似数据准备及实战
  9. MATLAB 半球面
  10. python学习之第二课时--运行程序和字符编码