Python中模块(Module)和包(Package)的区别详解


Posted in Python onAugust 07, 2019

1. 模块(Module)

在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。
为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就称之为一个模块(Module)。

使用模块有什么好处?

最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块。

使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中,因此,我们自己在编写模块时,不必考虑名字会与其他模块冲突。但是也要注意,尽量不要与内置函数名字冲突。

你也许还想到,如果不同的人编写的模块名相同怎么办?为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。

举个例子,一个abc.py的文件就是一个名字叫abc的模块,一个xyz.py的文件就是一个名字叫xyz的模块。
现在,假设我们的abc和xyz这两个模块名字与其他模块冲突了,于是我们可以通过包来组织模块,避免冲突。方法是选择一个顶层包名,比如mycompany,按照如下目录存放

mycompany
├─ __init__.py
├─ abc.py
└─ xyz.py

引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。现在,abc.py模块的名字就变成了mycompany.abc,类似的,xyz.py的模块名变成了mycompany.xyz。

请注意,每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是mycompany。

类似的,可以有多级目录,组成多级层次的包结构。比如如下的目录结构:

mycompany
 ├─ web
 │ ├─ __init__.py
 │ ├─ utils.py
 │ └─ www.py
 ├─ __init__.py
 ├─ abc.py
 └─ xyz.py

文件www.py的模块名就是mycompany.web.www

Notes: 自己创建模块时要注意命名,不能和Python自带的模块名称冲突。例如,系统自带了sys模块,自己的模块就不可命名为sys.py,否则将无法导入系统自带的sys模块。

2. 使用模块

Python本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用。

我们以内建的sys模块为例,编写一个hello的模块:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
#!/usr/bin/env python3 
# -*- coding: utf-8 -*-

' a test module '

__author__ = 'Michael Liao'

import sys

def test():
  args = sys.argv  # argv参数用列表存储命令行的所有参数
  if len(args)==1: # 当列表长度为1时即只有一个参数时
    print('Hello, world!')
  elif len(args)==2: # 当命令行有两个参数时
    print('Hello, %s!' % args[1])
  else:
    print('Too many arguments!')

if __name__=='__main__':
  test()

第1行和第2行是标准注释,第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行,第2行注释表示.py文件本身使用标准UTF-8编码;

第4行是一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;

第6行使用__author__变量把作者写进去,这样当你公开源代码后别人就可以瞻仰你的大名;

以上就是Python模块的标准文件模板,当然也可以全部删掉不写,但是,按标准办事肯定没错。

后面开始就是真正的代码部分。

你可能注意到了,使用sys模块的第一步,就是导入该模块:

import sys

导入sys模块后,我们就有了变量sys指向该模块,利用sys这个变量,就可以访问sys模块的所有功能。

sys模块有一个argv变量,用list存储了命令行的所有参数。argv至少有一个元素,因为第一个参数永远是该.py文件的名称,例如:

运行python3 hello.py获得的sys.argv就是['hello.py'],注意这里python3不算是参数;

运行python3 hello.py Michael获得的sys.argv就是['hello.py', 'Michael]。

最后,注意到这两行代码:

if __name__=='__main__':
  test()

当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。

我们可以用命令行运行hello.py看看效果:

$ python3 hello.py
Hello, world!
$ python hello.py Michael
Hello, Michael!

如果启动Python交互环境,再导入hello模块:

>>> import hello
>>>

导入时,没有打印Hello, word!,因为没有执行test()函数。

调用hello.test()时,才能打印出Hello, word!:

>>> hello.test()
Hello, world!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python操作xml文件详细介绍
Jun 09 Python
numpy返回array中元素的index方法
Jun 27 Python
python求解数组中两个字符串的最小距离
Sep 27 Python
Python Flask 搭建微信小程序后台详解
May 06 Python
python BlockingScheduler定时任务及其他方式的实现
Sep 19 Python
Pandas操作CSV文件的读写实现方法
Nov 13 Python
Python:二维列表下标互换方式(矩阵转置)
Dec 02 Python
Python 实现自动获取种子磁力链接方式
Jan 16 Python
Python 添加文件注释和函数注释操作
Aug 09 Python
selenium判断元素是否存在的两种方法小结
Dec 07 Python
Python使用Opencv实现边缘检测以及轮廓检测的实现
Dec 31 Python
Python实现查询剪贴板自动匹配信息的思路详解
Jul 09 Python
python的常见矩阵运算(小结)
Aug 07 #Python
python字典的setdefault的巧妙用法
Aug 07 #Python
解决Django中调用keras的模型出现的问题
Aug 07 #Python
python 字典 setdefault()和get()方法比较详解
Aug 07 #Python
与Django结合利用模型对上传图片预测的实例详解
Aug 07 #Python
如何用Python来搭建一个简单的推荐系统
Aug 07 #Python
PIL对上传到Django的图片进行处理并保存的实例
Aug 07 #Python
You might like
第九节 绑定 [9]
2006/10/09 PHP
php启动时候提示PHP startup的解决方法
2013/05/07 PHP
jQuery 图像裁剪插件Jcrop的简单使用
2009/05/22 Javascript
一步一步教你写一个jQuery的插件教程(Plugin)
2009/09/03 Javascript
js中parseFloat(参数1,参数2)定义和用法及注意事项
2013/01/27 Javascript
原生javascript实现Tab选项卡切换功能
2015/01/12 Javascript
基于JavaScript实现一定时间后去执行一个函数
2015/12/14 Javascript
JS简单实现DIV相对于浏览器固定位置不变的方法
2016/06/17 Javascript
jQuery多个版本和其他js库冲突的解决方法
2016/08/11 Javascript
javascript动画之磁性吸附效果篇
2016/12/09 Javascript
jQuery插件zTree实现删除树节点的方法示例
2017/03/08 Javascript
Three.js利用顶点绘制立方体的方法详解
2017/09/27 Javascript
微信小程序使用swiper组件实现层叠轮播图
2018/11/04 Javascript
Vue 报错TypeError: this.$set is not a function 的解决方法
2018/12/17 Javascript
详解Vue.js v-for不支持IE9的解决方法
2018/12/29 Javascript
详解vue中多个有顺序要求的异步操作处理
2019/10/29 Javascript
vue 中固定导航栏的实例代码
2019/11/01 Javascript
javascript自定义右键菜单插件
2019/12/16 Javascript
nodejs制作小爬虫功能示例
2020/02/24 NodeJs
[10:34]DOTA2上海特级锦标赛全纪录
2016/03/25 DOTA
python 读取鼠标点击坐标的实例
2018/12/29 Python
使用python实现CGI环境搭建过程解析
2020/04/28 Python
python用什么编辑器进行项目开发
2020/06/17 Python
python获取百度热榜链接的实例方法
2020/08/25 Python
Python如何telnet到网络设备
2021/02/18 Python
纯CSS3实现滚动的齿轮动画效果
2014/06/05 HTML / CSS
html5 sessionStorage会话存储_动力节点Java学院整理
2017/07/06 HTML / CSS
HTML5 新事件 小结
2009/07/16 HTML / CSS
物流专业大学生职业生涯规划书范文
2014/01/15 职场文书
投标承诺书范本
2014/03/27 职场文书
企业形象策划方案
2014/05/29 职场文书
2014年采购员工作总结
2014/11/18 职场文书
乡镇法制宣传日活动总结
2015/05/05 职场文书
承兑汇票延期证明
2015/06/23 职场文书
创业计划书之干洗店
2019/09/10 职场文书
解决python绘图使用subplots出现标题重叠的问题
2021/04/30 Python