Python: if __name__ == "__main__"
来源:互联网 发布:网络电视台广告语 编辑:程序博客网 时间:2024/05/07 15:51
http://luy.li/2010/05/31/python__name__main__/
为什么python里要 if __name__ == ‘__main__’:
尽管python允许你像shell脚本一样,把大段的代码堆积着写,但是,很多python入门的书,都会建议你把代码写成一个函数,然后在最后面统一调用,例如这样:
很多文章都会说这个是由于代码风格之类的原因,但是其实,不这样写,有时候也是会直接导致出错的。
举个例子,打开《A Byte of Python》的类变量那节,可以这里看在线版本,然后把中间的那示例代码复制下来,运行,可以看到,确实能得到预期正确的结果。
但是,现在把那代码里的所有“swaroop”换成“xxx1”,再把所有“kalam”换成“yyy1”,再运行,就会在程序运行的最后时刻,得到这么一个奇怪的错误(Python 2.6.5下实验):Exception AttributeError: "'NoneType' object has no attribute 'population'" in <bound method="" person.__del__="" of="" <__main__ person="" instance="" at="" 0xb689090c="">> ignored
也就是说,换了个变量名,程序就出错了。。。
究其原因,应该是python在最后析构所有类和对象的时候,并没有处理这些对象之间的依赖关系,而是根据变量名来决定某种顺序操作了。从而导致Person
类本身,先于yyy2
被干掉了,所以在解构yyy2
的时候,执行它的__del__()
方法,却发现父类都已经没有了~~
这应该确实算是python解析器的bug,但是,如果那把这个例子里的所有class Person以外的代码,写到一个main()
函数里,再通过上述方法调用的话,就不会发生这种错误了。
所以,大家最好还是别太在意多几行代码,养成这个好习惯吧。
http://f.dataguru.cn/thread-186411-1-1.html
__name__是指示当前py文件调用方式的方法。如果它等于"__main__"就表示是直接执行,如果不是,则用来被别的文件调用,这个时候if就为False,那么它就不会执行最外层的代码了。
比如你有个Python文件里面
def XXXX():
#body
print "asdf"
这样的话,就算是别的地方导入这个文件,要调用这个XXXX函数,也会执行print "asdf",因为他是最外层代码,或者叫做全局代码。但是往往我们希望只有我在执行这个文件的时候才运行一些代码,不是的话(也就是被调用的话)那就不执行这些代码,所以一般改为
def XXXX():
#body
if __name__="__main__":
print "asdf"
http://keliang.blog.51cto.com/3359430/649318
http://blog.sina.com.cn/s/blog_605f5b4f0101c96w.html
答案源于:http://stackoverflow.com/questions/419163/what-does-if-name-main-do,example是自己写的。
__name__
"__main__"
.__name__
http://www.crifan.com/python_detailed_explain_about___name___and___main__/
【整理】Python中的__name__和__main__含义详解
背景
在写Python代码和看Python代码时,我们常常可以看到这样的代码:
def
main():
......
if
__name
=
=
"__main__"
:
main();
其中的函数名main,也可以是其他任意的,你所设置的名字。
这里,就出现了,我们此处所要解释的
__name__和__main__
__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?
的代码来详细解释一下。
作为普通的代码,我们是可以这么写的:
#!/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
);
对应的,运行结果也是很正常的:
E:\Dev_Root\python\__name___and___main__>__name___and___main__.py
test
: square(42) == 1764
但是呢,往往我们所见到的,和我们以后自己也会遇到的,自己写的,有条理的,可复用的做法,那肯定是
那对应的square等函数,专门放到一个文件中,然后被别人调用,此时,就是这样的:
对应的模块文件是mymath.py,里面有我们实现的函数square:
#!/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函数:
#!/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
);
然后运行结果是:
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改为:
#!/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执行的是否正确:
E:\Dev_Root\python\__name___and___main__>mymath.py
test
: square(42) == 1764
2.同时,作为mymath.py的调用者__name___and___main__.py,在import mymath的时候,也不会看到对应的代码执行的结果了:
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改为:
#!/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了:
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__
也有个例子,相对更加简洁,需要的可以参考一下。
摘录其代码如下:
#!/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声明,否则,是会出现错误:
添加了coding声明后,就正常了。
然后,最终的测试的代码是:
#!/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'
和
#!/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
最终,测试出来的效果是:
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
http://stackoverflow.com/questions/419163/what-does-if-name-main-do
Expanding a bit on Harley's answer...
When the Python interpreter reads a source file, it executes all of the code found in it. Before executing the code, it will define a few special variables. For example, if the python interpreter is running that module (the source file) as the main program, it sets the special __name__
variable to have a value "__main__"
. If this file is being imported from another module, __name__
will be set to the module's name.
In the case of your script, let's assume that it's executing as the main function, e.g. you said something like
python threading_example.py
on the command line. After setting up the special variables, it will execute the import
statement and load those modules. It will then evaluate the def
block, creating a function object and creating a variable called myfunction
that points to the function object. It will then read the if
statement and see that __name__
does equal "__main__"
, so it will execute the block shown there.
One of the reasons for doing this is that sometimes you write a module (a .py
file) where it can be executed directly. Alternatively, it can also be imported and used in another module. By doing the main check, you can have that code only execute when you want to run the module as a program and not have it execute when someone just wants to import your module and call your functions themselves.
See this page for some extra details.
When your script is run by passing it as a command to the Python interpreter,
python myscript.py
all of the code that is at indentation level 0 gets executed. Functions and classes that are defined are, well, defined, but none of their code gets ran. Unlike other languages, there's no main()
function that gets run automatically - the main()
function is implicitly all the code at the top level.
In this case, the top-level code is an if
block. __name__
is a built-in variable which evaluate to the name of the current module. However, if a module is being run directly (as in myscript.py
above), then __name__
instead is set to the string "__main__"
. Thus, you can test whether your script is being run directly or being imported by something else by testing
if __name__ == "__main__": ...
If that code is being imported into another module, the various function and class definitions will be imported, but the main()
code won't get run. As a basic example, consider the following two scripts:
# file one.pydef func(): print("func() in one.py")print("top-level in one.py")if __name__ == "__main__": print("one.py is being run directly")else: print("one.py is being imported into another module")# file two.pyimport oneprint("top-level in two.py")one.func()if __name__ == "__main__": print("two.py is being run directly")else: print("two.py is being imported into another module")
Now, if you invoke the interpreter as
python one.py
The output will be
top-level in one.pyone.py is being run directly
If you run two.py
instead:
python two.py
You get
top-level in one.pyone.py is being imported into another moduletop-level in two.pyfunc() in one.pytwo.py is being run directly
Thus, when module one
gets loaded, its __name__
equals "one"
instead of __main__
.
The simplest explanation for the __name__
variable (imho) is the following:
Create the following files.
# a.pyimport b
and
# b.pyprint "Hello World from %s!" % __name__if __name__ == '__main__': print "Hello World again from %s!" % __name__
Running them will get you this output:
$ python a.pyHello World from b!$ python b.pyHello World from __main__!Hello World again from __main__!
- python if __name__ = '__main__'
- 【Python】if __name__ == '__main__'
- 【Python】if __name__ == '__main__'
- python中if __name__ == '__main__':
- Python: if __name__ == "__main__"
- Python 之 if __name__ == '__main__':
- python if __name__ == '__main__' 详解
- 【Python】if __name__ == "__main__":
- python中if __name__ == '__main__'
- Python 之 if __name__ == '__main__'
- python基础:if __name__ == '__main__'
- 【Python基础】if __name__ == '__main__'
- 【python】if __name__ == "__main__"
- python中if __name__ == '__main__'
- Python基础if __name__ == '__main__'
- python中if __name__ == '__main__'
- python中if __name__=="__main__":
- Python-if __name__ == '__main__'
- Android逆向工程-破解 哈皮妹-萝莉
- linux下升级openssh参考[不建议采用此法安装]
- Ubuntu中文输入法和忘记密码之后登陆的方法
- box2d 简介
- 80端口被屏蔽怎么办,利用80端口映射发布网站
- Python: if __name__ == "__main__"
- glew, glee与 gl, glu, glut, glx, glext的区别和关系【转】
- 编译Android 4.0.3的常见错误
- 线程与进程,Thread的run()与start()的区别
- Qt实现Windows远程控制
- 详解RSYNC 好文
- C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转
- Android源码分析-Activity的启动过程
- 什么都没做的一天