Python中的__name__和__main__含义详解
2016-01-04 17:00
746 查看
1背景
在写Python代码和看Python代码时,我们常常可以看到这样的代码:?
这里,就出现了,我们此处所要解释的
__name__和__main__
__name__和__main的含义
其实,对于Python中的这类问题,根据我之前的:【整理】如何学习Python + 如何有效利用Python有关的网络资源 + 如何利用Python自带手册(Python Manual)
中的介绍,最好的学习的方法,其实就是去看官网文档:
__name__的含义
另外还有几处的解释:
Modules…
Predefined (writable) attributes: __name__ is the module’s name;
… Classes…
Special attributes: __name__ is the class name;
从这几处的解释,我们很容易理解其基本的意思:
__name__,
如果是放在Modules模块中,就表示是模块的名字;
如果是放在Classs类中,就表示类的名字;
__main__的含义
同理,先去官网文档中看对应的解释:对应的其他几处的解释是:
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?
的代码来详细解释一下。
作为普通的代码,我们是可以这么写的:
?
?
那对应的square等函数,专门放到一个文件中,然后被别人调用,此时,就是这样的:
对应的模块文件是mymath.py,里面有我们实现的函数square:
?
?
?
test: square(42) == 1764
而这样的内容,很明显,是作为我模块的调用者,不希望看到的。也不关心的。
此时,我们所希望的是:
作为模块mymath.py本身,希望有自己的相关的调试的代码,用于调试自己模块函数,演示如何使用等等代码;
但是又不希望在被别的,本模块的调用者,所执行到,所看到;
此时,就可以用上述的__main__来实现了:
把mymath.py改为:
?
1. 作为mymath.py本身,自己运行时,可以运行到此处的代码,调试,验证自己的函数square执行的是否正确:
?
?
作为模块mymath.py本身:
作为脚本自己去运行的话,对应的模块名,就是上面所解释的,始终叫做__main__
关于这点,上述代码已经验证过了。因为mymath.py中的__name__,就是对应的,内置的变量,通过判断,的确是__main__,然后才会去执行到对应的模块的测试代码的。
如果被当做一个模块被别人调用的时候,对应的模块mymath.py的模块名,就是mymath;
关于这点,我们可以来验证一下,把__name___and___main__.py改为:
?
?
示例2
另外,这里:A Byte of Python – A module’s __name__
也有个例子,相对更加简洁,需要的可以参考一下。
摘录其代码如下:
?
__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声明后,就正常了。
然后,最终的测试的代码是:
?
?
?
python文件本身自己运行时,显示的是:This program is being run by itself
Python文件被别人import导入时,显示的是:I am being imported from another module
相关文章推荐
- python实战系列之RTX发送告警消息(四)
- python加密模块使用,aes128,ecb模式
- python @装饰器 简单理解
- pip管理的安装与使用——python包的安装
- Python将unicode编码字符串转化为中文
- python基础:列表生成式和生成器
- python语法十分钟
- PYTHON 验证码服务程序代码
- python手记(53)
- Python字符串特性及常用字符串方法的简单笔记
- 关于python的多线程问题
- python 之路-语法(一)
- 如何使用 Pylint 来规范 Python 代码风格
- python --subprocess
- python中常用的MySQL操作以及命令
- python --存储对象
- Python调用web service
- Python基础(一)Hello World!
- python 连接 mysql 错误
- Mac环境下,numpy升级问题。