Python复习小记 第九章 模块与包

9.1 模块的概念

模块是一个保存了Python代码的文件,其中可以包含变量、函数或类的定义,也可以包含其他各种Python语句。使用模块有以下3方面的优势。
(1)模块提高了代码的可维护性。在程序开发过程中,随着程序功能的增多,在一个文件中的代码会越来越长,从而造成程序不易维护,此时可以把相关功能的代码分配到一个模块里,从而使代码更易懂、更易维护。
(2)模块提高了代码的可重用性。在应用程序开发中,经常需要处理时间,此时不必在每个程序中写入时间的处理函数,只需导入time模块即可。
(3)模块避免了函数名和变量名冲突。由于相同名字的函数和变量可以分别存在于不同模块中,在编写模块时,不必考虑名字会与其他模块冲突(此处不考虑导包情况)。
在Python中,模块可以分为3类,具体如下所示:
内置标准模块(标准库)——Python自带的模块,如sys、os等。
自定义模块——用户为了实现某个功能自己编写的模块。
第三方模块——其他人已经编写好的模块。
一个Python程序可由若干模块构成,一个模块中可以使用其他模块的变量、函数和类等,如图所示。
在这里插入图片描述

在图中, a.py是一个顶层模块(又称主模块),其中使用了自定义模块b.py和内置标准模块,b.py也使用了内置标准模块。
接下来简单演示模块的使用,如例所示。
在这里插入图片描述
在例中,程序使用math模板中的sqrt()函数可以很方便地计算出9的算术平方根。

9.2 模块的导入

模块需要先导入,然后才能使用其中的变量或函数。在Python中使用关键字import导入某个模块,其语法格式如下:
在这里插入图片描述

其中,import用于导入整个模块,可用as为导入的模块指定一个别名。使用import导入模块后,模块中的对象均以“模块名(别名).对象名称”的方式来引用。
接下来演示import关键字导入模块,如例所示。
在这里插入图片描述
在例中,第1行为math模块指定别名m,第2行一次导入多个模块。
此外,若只想导入模块中的某个对象,则可以使用from导入模块中的指定对象,其语法格式如下:
在这里插入图片描述
注意使用from导入的对象可以直接使用,不需要使用模块名作为限定符,如例所示。
在这里插入图片描述
在例中,第1行通过from关键字从math模块中导入sqrt()函数,然后再通过as关键字为sqrt()函数指定别名st。
import与from导入模块各有特点,使用import导入模块时比较简单,使用from导入模块时需列出想要导入的对象名,但无论哪种导入方式,模块只能一次导入。另外,注意模块整体导入的开销是比较大的。

9.3 内置标准模块

Python标准库中包括了许多模块,从Python语言自身特定的类型到一些只用于少数程序的模块,本节主要介绍基础阶段常见的内置标准模块。

9.3.1 sys模块

sys模块是Python标准库中最常用的模块之一。通过它可以获取命令行参数,从而实现从程序外部向程序内部传递参数的功能,也可以获取程序路径和当前系统平台等信息。
接下来演示通过sys模块获取命令行参数,如例所示。
在这里插入图片描述
在例中,注意执行程序时,需要开启终端模式(在PyCharm中,选择View->Tool Windows->View->Terminal选项即可)。从程序运行结果可以看出,在命令行中输入了3个参数,分别为’9-4.py’、 ‘xiaoqian’、‘666’。
在导入模块时,用户省略了模块文件的路径和扩展名,但Python解释器可以找到对应的文件,这是因为Python解释器会按特定的路径来搜索模块文件,用户可以通过sys.path获取搜索模块的路径,如例所示。
在这里插入图片描述
在例中,第2行通过print()函数打印出搜索模块路径。sys.path通常由4部分组成,具体如下所示:
程序的当前目录(可用os模块中的getcwd()函数查看当前目录名称)。
操作系统的环境变量PYTHONPATH中包含的目录(如果存在)。
Python标准库目录。
任何.pth文件包含的目录(如果存在)。

9.3.2 platform模块

platform模块提供了很多方法用于获取有关开发平台的信息,如例所示。
在这里插入图片描述
在例中,通过platform模块可以获取有关开发平台的相关信息。

9.3.3 random模块

random模块用于生成随机数,其中常用的函数如表所示。
在这里插入图片描述
接下来演示random模块中主要函数的用法,如例所示。
在这里插入图片描述

9.3.4 time模块

time模块用于获取并处理时间,Python中有两种时间表示方式,接下来分别介绍每种表示方式。
1.时间戳
时间戳是指从格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。在time模块中的time()函数可以获取当前时间的时间戳,如例所示。
在这里插入图片描述
在例中,通过time模块中time()函数获取当前时间的时间戳,但从该结果中不能直接得出它所表示的时间,此时可以将该结果转换为时间元组,再进行格式化输出。
2. 时间元组
时间元组struct_time包含9个元素,具体如表所示。
在这里插入图片描述
在time模块中,localtime()函数可以将一个时间戳转为一个当前时区的时间元组,如例所示。
在这里插入图片描述
在上例中,程序通过time模块中localtime()函数可以将时间戳转为时间元组。从运行结果可发现,时间元组表示时间也不易观察,此时可以通过strftime()函数将时间元组格式化,如例所示。
在这里插入图片描述
在例中,通过time模块中strftime ()函数可以将时间元组格式化。该函数中第一个参数为格式化的时间字符串,其中格式化符号如表所示。
在这里插入图片描述
Python中还有许多内置标准模块,可以通过在终端模式下输入“help(‘模块名’)”查看该模块包含的对象及用法,如通过help(‘time’)查看time模块的用法,如图所示。
在这里插入图片描述

9.4 自定义模块

毕竟内置标准模块的功能有限,开发人员经常需要自定义函数,此时可以把函数组织到模块中,其他程序只需导入便可以引用模块中定义的函数,这种做法不仅使程序具有良好的结构,而且增加了代码的重用性。
在Python中,每个.py文件都可以作为一个模块,模块的名字就是文件的名字,接下来演示如何自定义模块,假设mymodule.py文件中包含2个函数,具体如下所示:
在这里插入图片描述
如果创建的模块mymodule.py与例9-11.py保存在同一目录下,此时可以通过导入该模块便可引用其中包含的函数,如例所示。
在这里插入图片描述
在例中,程序导入mymodule模块并引用其中包含的函数。
在实际开发中,自定义完模块后,为了保证模块编写正确,一般需要在模块中添加测试信息,具体如下所示:
在这里插入图片描述
此时,若执行9-11.py代码,则运行结果如图所示。
在这里插入图片描述
从程序运行结果可发现,9-11.py执行了mymodule.py中的测试代码,这是不期望出现的结果。为了解决上述问题,Python提供了一个__name__属性,它存在于每个.py文件中。当模块被其他程序导入使用时,模块__name__属性值为模块文件的主名;当模块直接被执行时,__name__属性值为’main’。
接下来修改mymodule.py文件,使其作为模块导入时不执行测试代码,具体如下所示:
在这里插入图片描述
修改完成后,再次执行9-11.py代码,运行结果如图所示。
在这里插入图片描述

从程序运行结果可发现,执行9-11.py代码时,程序并没有执行mymodule模块中的测试代码。

9.5 包的概念

Python的程序由包、模块和函数组成。包是由一系列模块组成的集合,模块是处理某一类问题的函数和类的集合,它们之间的关系如图所示。
在这里插入图片描述

Python提供了许多有用的工具包,如字符串处理、Web应用、图像处理等,这些自带的工具包和模块安装在Python的安装目录下的Lib子目录中。包是一个至少包含__int__.py文件的文件夹,init.py文件一般用来进行包的某些初始化工作或者设置__all__值,其内容可以为空。
假设首先在包pack中创建两个子包:pack1和pack2,然后在包pack1中定义模块myModule1,在包pack2中定义模块myModule2,最后在包pack中定义一个模块main,调用子包pack1和pack2中的模块,具体结构如下所示:
在这里插入图片描述
其中,pack1包下的__init__.py文件内容如下:
在这里插入图片描述
pack1包下的myModule1.py文件内容如下:
在这里插入图片描述
pack2包下的__init__.py文件内容如下:
在这里插入图片描述
pack2包下的myModule2.py文件内容如下:
在这里插入图片描述
pack包下的__init__.py文件内容如下:
在这里插入图片描述
pack包下的main.py文件内容如下:
在这里插入图片描述
运行main.py程序,则运行结果如图所示。
在这里插入图片描述
运行main.py程序,则运行结果如图所示。
在这里插入图片描述

从程序运行结果可发现,导入模块过程中遇到的所有__init__.py文件都会被执行。从包中导入单独的模块可以使用以下种3方法:
在这里插入图片描述
当需要导入某个包下的所有模块时,不可以直接使用如下语句:
在这里插入图片描述
这时需要使用__all__记录当前包所包含的模块,例如在pack1包的__init__.py文件中第一行添加如下代码:
在这里插入图片描述

其中方括号中的内容是模块名的列表,如果模块数量超过两个,使用逗号分开。同理,在pack2包的__init__.py文件中也添加一行类似的代码:
在这里插入图片描述
这样就可以在main.py模块中一次导入pack1、pack2包中所有的模块,pack包下的main.py文件内容如下:
在这里插入图片描述
运行main.py程序,运行结果如图所示。
在这里插入图片描述

如果pack1包下的myModule1.py文件需要引用pack2包下的myModule2模块,默认情况下,myModule1.py文件是找不到myModule2模块,此时需要按相对位置引入模块,修改myModule1.py文件,具体如下所示:
在这里插入图片描述
其中,“…”表示包含from导入命令的模块文件所在路径的上一级目录,运行main.py程序,则运行结果如图所示。
在这里插入图片描述

9.6 包的发布

本节将演示如何将写好的模块进行打包和发布,最简单的方法是将包直接复制到Python的lib目录,但此方式不便于管理与维护,存在多个Python版本时会非常混乱。接下来通过编写setup.py来对9.5节介绍的pack模块进行打包。
(1)在pack所在的文件目录下新建setup.py、MANIFEST.in、README.txt文件,其目录结构如下:
在这里插入图片描述

(2)打开setup.py文件,编辑其内容如下:
在这里插入图片描述
其中,packages指明将要发布的包。
打开MANIFEST.in文件,编辑其内容如下:
在这里插入图片描述
该文件列出各种希望包含在包中的非源代码。
README.txt文件中的内容为提示使用者如何使用该包中的模块。
(3)在终端模式下,进入pack包所在的文件目录执行如下命令:
在这里插入图片描述
该命令可以构建包,具体执行过程如图所示。
在这里插入图片描述

执行完该命令后,目录结构如下所示:
在这里插入图片描述
(4)接着在终端模式下输入以下命令:
在这里插入图片描述
该命令可以生成最终发布的压缩包,具体执行过程如图所示。
在这里插入图片描述

执行完该命令后,目录结构如下所示:
在这里插入图片描述
其中,dist目录下myProject-1.0.tar.gz文件为将要发布的包,开发者可以将此文件发布给其他人或上传到Python社区供更多的开发者下载。

9.7 包的安装

9.6节讲解了如何发布自己制作的包,本节讲解如何安装其他开发者发布的包(以9.6节最终生成的压缩包为例)。
(1)进入压缩包所在的文件目录并对其进行解压,解压后的文件目录如下所示:
在这里插入图片描述(2)在终端模式下,进入myProject-1.0目录下执行如下命令:

在这里插入图片描述
该命令具体执行过程如图所示。
在这里插入图片描述
通过该命令就可以将pack包安装到系统(即Python路径)中,即该包存在于D:\python3.6.2\Lib\site-packages(本书中Python的安装目录为D:\python3.6.2)。

9.8 小案例

大家在使用手机QQ进行群聊时,经常会有小伙伴发红包,如图所示。
在这里插入图片描述

发红包模块需具备以下3点要求:
设定红包金额与数量。
金额数最大的为运气王。
随机分配金额。
接下来按照上述要求编写发红包功能模块,具体实现如例所示。
在这里插入图片描述
在Python中不建议使用浮点数进行精确计算,因为往往会得到意想不到的结果。大家可在实际开发中导入decimal模块来处理浮点数存在的误差。

总结

本章主要介绍了Python程序中的模块与包,包括模块的概念、模块的导入、内置标准模块、自定义模块、包的概念、包的发布及安装。在开发应用时可以将程序组织成模块架构,这样不仅可以提高代码的重用性,而且便于将复杂任务分解并进行分块调试。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值