__name__和__main的含义
其实,对于Python中的这类问题,根据我之前的:
【整理】如何学习Python + 如何有效利用Python有关的网络资源 + 如何利用Python自带手册(Python Manual)
中的介绍,最好的学习的方法,其实就是去看官网文档:
__name__的含义
另外还有几处的解释:
从这几处的解释,我们很容易理解其基本的意思:
__name__,
如果是放在Modules模块中,就表示是模块的名字;
如果是放在Classs类中,就表示类的名字;
__main__的含义
同理,先去官网文档中看对应的解释:
对应的其他几处的解释是:
说实话,对于__main__,上述的解释,并不是那么容易看的懂。
其实要看懂上面的解释,我们首先要知道的一些前提是:
python代码,是可以直接一行行写出来,然后去运行,是可以的。但是这只是针对我们的小程序来说的。
更多的Python代码,是写成更加通用的,可以被调用的,可以重复利用的,模块的形式;
所以都是写在对应的函数里面的。
而作为模块,就是上面的解释中的:
模块第一次被导出(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
16
|
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
【整理】Python中的__name__和__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
16
|
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
【整理】Python中的__name__和__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
15
|
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
【整理】Python中的__name__和__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
17
|
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
【整理】Python中的__name__和__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改为:
- 如果被当做一个模块被别人调用的时候,对应的模块mymath.py的模块名,就是mymath;
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__含义详解
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了。