Python中的模块包括系统模块、第三方模块和用户自定义模块,它们实质上是以.py为扩展名的Python文件
通过导入模块,可以使用该模块中的变量、函数和类等
- 模块化的程序设计思想
- 模块的导入与创建
- 模块的搜索路径
- 模块的属性
- 包及模块的打包发布
- 模块安装及其他
模块化的程序设计思想
模块设计的一般原则:
1.先设计API,再实现模块
2.控制模块的规模,只为客户端提供需要的函数。实现包含大量函数的模块会导致模块的复杂性。例如,Python的math模块就不包含正割函数、余割函数和余切函数,因为这些函数很容易通过函数math.sinn()、math.cos()和math.tan()的计算而得
3.在模块中编写测试代码,并消除全局代码
4.使用私有函数实现不被外部客户端调用的模块函数
5.通过文档提供模块帮助信息
模块的导入与创建
- | 方式一 | 方式二 |
---|---|---|
模块的导入 | import 模块名 | from 模块名 import 函数名 或:from 模块名 import * |
导入示例 | import combinatorial | from combinatorial import fac,comb 或者:from combinatorial import * |
函数调用 | 模块名.函数名 | 函数名 |
函数调用示例 | combinatorial.fac(10) | fac(10) |
模块导入(import)
使用import格式导入模块时,模块中的所有内容都会被导入到当前程序中,可以一次导入多个模块,每个模块名之间使用","分割。在命令行中导入某个模块,用户便可以调用指定模块中的任意方法,例如:
import 模块1,模块2,...
模块.方法()
模块导入(from 模块名 import 方法/类/对象)
使用import语句导入模块之后,每次调用模块中的内容时,都需要添加前缀“模块名”,若某些内容在导入模块的文件中使用的频率较高,亦或模块名较长,使用这种方法显然比较繁琐,所以Python中提供了“from…import…”语句,该语句可导入模块中的部分内容,用法如下:
from 模块 import 方法/类/对象
以此语句导入的方法,类和对象等无需添加“模块名.”前缀,可直接使用,例如:
模块导入(from 模块名 import *)
from…import * 遵循from…import…语句的格式,其中通配符“ * ” 指代指定模块中的全部方法,以random模块为例,再导入“ * ”之后,用户可使用random模块中的全部方法,例如:
- Python模块对应于包含Python代码的源文件(其扩展名为.py),在文件中可以定义变量、函数和类
- 在模块中,除了可以定义变量、函数和类之外,还可以包含一般的语句,称之为主块(全局语句)。当运行该模块,或导入该模块时,主块语句将依次进行。
接下来举个例子:
先创建一个文件夹,然后在文件夹内部创建一个.py文件,在文件里面写好自己模块内容,比如我自己就借用了一段斐波那契的代码
def fib(n):
a, b = 0, 1
while b < n:
print(b, end=' ')
a, b = b, a+b
print()
def fib2(n):
result = []
a, b = 0, 1
while b < n:
result.append(b)
a, b = b, a+b
return result
然后我们就可以导入模块
模块的搜索路径
- sys模块的sys.path属性返回一个路径列表
使用import语句导入模块时,系统自动从该列表的路径中搜索模块,如果没有找到,则程序报错 - sys.path的本质是列表,因此用户可以通过列表的内置方法append动态地向sys.path中添加模块所在路径
模块的导入顺序
- 导入模块时,解释器按下列目录搜索路径和文件搜索顺序查找并导入文件。目录搜索路径为:
1.当前目录。启动交互式Python的目录,或Python主程序位于的目录
2.操作系统环境变量PYTHONPATH中指定的目录
3.Python标准库目录
模块的属性
__ all __属性: __ all __变量控制模块里哪些功能可以使用*号导入
- 每个模块都有一个名称,通过特殊变量__name__可以获取模块的名称
- 特别的,当一个模块被用户单独运行,其__name__的值为’__ main __’。故可以把模块源代码文件的测试代码写在相应的测试判断中,以保证只有单独运行时,才会运行测试代码
- 直接运行模块代码时,__ name __取值为“ __ main __”
- 导入模块时,__ name __ 取值为模块名称
模块的导入特性:模块在被导入时,会被执行一次,这个过程也叫做加载,一个模块即便被多次导入程序,也只会被加载一次
- .pyc文件是经过编译后的字节码,这样下次导入时,如果模块源代码.py文件没有修改(通过比较两者的时间戳),则直接导入.pyc文件,从而提高程序效率
- 按字节编译的.pyc文件是在导入模块时,python解释器自动完成,无需程序员手动编译
包及模块的打包发布
包是Python引入的分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的Python的应用环境。引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。
每一个Python的包目录下面都会有名为__ init __.py的特殊文件,该文件可以为空文件,但是必须存在,它表明这个目录不是普通的目录结构,而是一个包,里面包含模块
为了更好地组织模块,开发人员通常选择将项目中的模块划分为包。简单来说,包(package)是一个包含__ init __.py 文件的目录,该目录中还包含一些模块或子包,如下所示
from distutils.core import setup
setuo(
name="itheima", #包名
version="1.0", #版本号
description="itheima belongs to itcast", #包的描述信息
py_modules=['suba.aa', 'suba.bb', 'subb.cc', 'subb.dd'] #包中含有的模块
)
其中setup为一个函数,包含5个参数,依次为:包名、版本号、描述信息、作者以及包中含有的模块,实际上setup函数中不只有这些参数,但这些参数也不是必需的,用户可有选择地进行设置
在当前路径下打开命令行窗口,使用build命令构建模块
python setup.py build
经此操作后,当前目录中会创建一个名为build的文件夹,其中包含一个名为lib的目录,该目录中存储了待发布模块的备份。build文件夹中的目录结构如下所示:
python setup.py sdist
经此操作后会创建一个名为dist的文件夹和MANIFEST的文件,dist文件夹里面就有我们需要的包啦
自定义包的安装
python setup.py install
pip list #查看已安装的第三方库
pip show <库名称> #查看某个库的详细信息
模块的私有函数
- 实现模块时,有时候需要在模块中定义仅在模块中使用的辅助函数。辅助函数不提供给客户端直接调用,故称之为私有函数
- 按惯例,Python程序员使用下划线开始的函数名作为私有函数。私有函数客户端不应该直接调用,故API中不包括私有函数
- Python语言没有强制不允许调用私有函数的机制,程序员应该避免直接调用私有函数
编写模块文档字符串
- 在函数的第一个逻辑行的字符串称为函数的文档字符串。函数的文档字符串用于提供有关函数的帮助信息
- 文档字符串一般遵循下列惯例:文档字符是一个多行字符串;首行以大写字母开始,句号结尾;第二行是空行;从第三行开始是详细的描述
- 可以使用三种方法抽取函数的文档字符串帮助信息:①使用内置函数:help(函数名);②使用函数的特殊属性:函数名.__ doc __;③第三方自动化工具也可以抽取文档字符串信息,以形成帮助文档