python模块结构和布局与__name__ 指示模块被加载问题
2016-03-02 23:52
603 查看
用模块来合理组织你的 Python 代码是简单又自然的方法。你应该建立一种统一且容易阅读
的结构,并将它应用到每一个文件中去。下面就是一种非常合理的布局:
# (1) 起始行(Unix)
# (2) 模块文档
# (3) 模块导入
# (4) 变量定义
# (5) 类定义
# (6) 函数定义
# (7) 主程序
图 3–1 一个典型模块的内部结构图解。
(1) 起始行
通常只有在类 Unix 环境下才使用起始行,有起始行就能够仅输入脚本名字来执行脚本,无
需直接调用解释器。
(2)模块文档
简要介绍模块的功能及重要全局变量的含义,模块外可通过 module.__doc__ 访问这些内
容。
(3)模块导入
导入当前模块的代码需要的所有模块;每个模块仅导入一次(当前模块被加载时);函数
内部的模块导入代码不会被执行, 除非该函数正在执行。
(4)变量定义
这里定义的变量为全局变量,本模块中的所有函数都可直接使用。从好的编程风格角度说,
除非必须,否则就要尽量使用局部变量代替全局变量,如果坚持这样做,你的代码就不但容易
维护,而且还可以提高性能并节省内存。
(5)类定义语句
所有的类都需要在这里定义。当模块被导入时 class 语句会被执行, 类也就会被定义。类
的文档变量是 class.__doc__。
(6)函数定义语句
此处定义的函数可以通过 module.function()在外部被访问到,当模块被导入时 def 语句
会被执行, 函数也就都会定义好,函数的文档变量是 function.__doc__。
(7) 主程序
无论这个模块是被别的模块导入还是作为脚本直接执行,都会执行这部分代码。通常这里
不会有太多功能性代码,而是根据执行的模式调用不同的函数。
推荐代码风格:主程序调用 main()函数
主程序代码通常都和你前面看到的代码相似,检查 __name__ 变量的值然后再执行相应的
调用(参阅下一页的核心笔记)。主程序中的代码通常包括变量赋值, 类定义和函数定义,随
后检查__name__来决定是否调用另一个函数(通常调用 main()函数)来完成该模块的功能。主
程序通常都是做这些事。 不管用什么名字,我们想强调一点那就是:这儿是放置测试代码的好地
方。我们知道,大部分的 Python 模块都是用于导入调用的,直接运行模块
应该调用该模块的回归测试代码。
很多项目都是一个主程序,由它导入所有需要的模块。所以请记住,绝大部分的模块创建
的目的是为了被别人调用而不是作为独立执行的脚本。我们也很可能创建一个 Python 库风格的
模块,这种模块的创建目的就是为了被其他模块调用。总之,只有一个模块,也就是包含主程
序的模块会被直接执行,或由用户通过命令行执行,或作为批处理执行, 或由 Unix cron 任务
定时执行,或通过 Web 服务器调用,或通过 GUI 执行。
时刻记住一个事实,那就是所有的模块都有能力来执行代码。最高级别的 Python 语句--
也就是说, 那些没有缩进的代码行在模块被导入时就会执行, 不管是不是真的需要执行。由
于有这样一个“特性”,比较安全的写代码的方式就是除了那些真正需要执行的代码以外, 几
乎所有的功能代码都在函数当中。再说一遍, 通常只有主程序模块中有大量的顶级可执行代码,
所有其它被导入的模块只应该有很少的顶级执行代码,所有的功能代码都应该封装在函数或类
当中。
核心笔记:__name__ 指示模块应如何被加载
由于主程序代码无论模块是被导入还是被直接执行都会运行, 我们必须知道模块如何决定
运行方向。一个应用程序可能需要导入另一个应用程序的一个模块,以便重用一些有用的代码
(否则就只能用拷贝粘贴那种非面向对象的愚蠢手段)。这种情况下,你只想访问那些位于其
它应用程序中的代码,而不是想运行那个应用程序。因此一个问题出现了,“Python 是否有
一种方法能在运行时检测该模块是被导入还是被直接执行呢?” 答案就是......(鼓声雷
动).....没错! __name__ 系统变量就是正确答案。
如果模块是被导入, __name__ 的值为模块名字
如果模块是被直接执行, __name__ 的值为 '__main__'
的结构,并将它应用到每一个文件中去。下面就是一种非常合理的布局:
# (1) 起始行(Unix)
# (2) 模块文档
# (3) 模块导入
# (4) 变量定义
# (5) 类定义
# (6) 函数定义
# (7) 主程序
图 3–1 一个典型模块的内部结构图解。
(1) 起始行
通常只有在类 Unix 环境下才使用起始行,有起始行就能够仅输入脚本名字来执行脚本,无
需直接调用解释器。
(2)模块文档
简要介绍模块的功能及重要全局变量的含义,模块外可通过 module.__doc__ 访问这些内
容。
(3)模块导入
导入当前模块的代码需要的所有模块;每个模块仅导入一次(当前模块被加载时);函数
内部的模块导入代码不会被执行, 除非该函数正在执行。
(4)变量定义
这里定义的变量为全局变量,本模块中的所有函数都可直接使用。从好的编程风格角度说,
除非必须,否则就要尽量使用局部变量代替全局变量,如果坚持这样做,你的代码就不但容易
维护,而且还可以提高性能并节省内存。
(5)类定义语句
所有的类都需要在这里定义。当模块被导入时 class 语句会被执行, 类也就会被定义。类
的文档变量是 class.__doc__。
(6)函数定义语句
此处定义的函数可以通过 module.function()在外部被访问到,当模块被导入时 def 语句
会被执行, 函数也就都会定义好,函数的文档变量是 function.__doc__。
(7) 主程序
无论这个模块是被别的模块导入还是作为脚本直接执行,都会执行这部分代码。通常这里
不会有太多功能性代码,而是根据执行的模式调用不同的函数。
推荐代码风格:主程序调用 main()函数
主程序代码通常都和你前面看到的代码相似,检查 __name__ 变量的值然后再执行相应的
调用(参阅下一页的核心笔记)。主程序中的代码通常包括变量赋值, 类定义和函数定义,随
后检查__name__来决定是否调用另一个函数(通常调用 main()函数)来完成该模块的功能。主
程序通常都是做这些事。 不管用什么名字,我们想强调一点那就是:这儿是放置测试代码的好地
方。我们知道,大部分的 Python 模块都是用于导入调用的,直接运行模块
应该调用该模块的回归测试代码。
很多项目都是一个主程序,由它导入所有需要的模块。所以请记住,绝大部分的模块创建
的目的是为了被别人调用而不是作为独立执行的脚本。我们也很可能创建一个 Python 库风格的
模块,这种模块的创建目的就是为了被其他模块调用。总之,只有一个模块,也就是包含主程
序的模块会被直接执行,或由用户通过命令行执行,或作为批处理执行, 或由 Unix cron 任务
定时执行,或通过 Web 服务器调用,或通过 GUI 执行。
时刻记住一个事实,那就是所有的模块都有能力来执行代码。最高级别的 Python 语句--
也就是说, 那些没有缩进的代码行在模块被导入时就会执行, 不管是不是真的需要执行。由
于有这样一个“特性”,比较安全的写代码的方式就是除了那些真正需要执行的代码以外, 几
乎所有的功能代码都在函数当中。再说一遍, 通常只有主程序模块中有大量的顶级可执行代码,
所有其它被导入的模块只应该有很少的顶级执行代码,所有的功能代码都应该封装在函数或类
当中。
核心笔记:__name__ 指示模块应如何被加载
由于主程序代码无论模块是被导入还是被直接执行都会运行, 我们必须知道模块如何决定
运行方向。一个应用程序可能需要导入另一个应用程序的一个模块,以便重用一些有用的代码
(否则就只能用拷贝粘贴那种非面向对象的愚蠢手段)。这种情况下,你只想访问那些位于其
它应用程序中的代码,而不是想运行那个应用程序。因此一个问题出现了,“Python 是否有
一种方法能在运行时检测该模块是被导入还是被直接执行呢?” 答案就是......(鼓声雷
动).....没错! __name__ 系统变量就是正确答案。
如果模块是被导入, __name__ 的值为模块名字
如果模块是被直接执行, __name__ 的值为 '__main__'
相关文章推荐
- [notes]Iterator-1:Sentence class Python迭代器基本概念
- python ImportError: DLL load failed: %1 不是有效的 Win32 应用程序
- 机器学习实战之kNN
- 安装第三方库出现 Python version 2.7 required, which was not found in the registry
- Python识别网站验证码
- python爬虫-采集英语翻译
- Python 第五天 装饰器
- python之函数学习
- RabbitMQ学习小结(五)—— Topics[Python]
- RabbitMQ学习小结(六)—— RPC[Python]
- RabbitMQ学习小结(四)—— Routing[Python]
- RabbitMQ学习小结(三)—— Publish Subscribe[Python]
- RabbitMQ学习小结(二)—— Work Queues[Python]
- RabbitMQ学习小结(一)—— Hello World [Python]
- python切片解析
- python中的map,filter,zip函数
- python爬虫 bs4_4select()教程
- python爬虫 beutifulsoup4_1官网介绍
- python 使用不同的版本之间的切换
- Python中lambda表达式