目录
一、模块化设计理念
1.模块和包的进化史
- 1. Python 程序由模块组成。一个模块对应 python 源文件,一般后缀名是:.py。
- 2. 模块由语句组成。运行 Python 程序时,按照模块中语句的顺序依次执行。
- 3. 语句是 Python 程序的构造单元,用于创建对象、变量赋值、调用函数、控制语句等。
2.模块化编程的优势:
- 便于将一个任务分解成多个模块,实现团队协同开发,完成大规模程序
- 实现代码复用。一个模块实现后,可以被反复调用。
- 可维护性增强。
3.模块化编程的流程
- 设计 API,进行功能描述。 (API:应用程序编程接口,用于描述模块中提供的函数和类功能和使用方法描述,导入模块后可用过help()查看该模块的API)
- 编码实现 API 中描述的功能。
- 在模块中编写测试代码,并消除全局代码。
- 使用私有函数实现不被外部客户端调用的模块函数。
4.模块的创建和测试代码
每一个模块都有名称,通过特殊变量__name__可以获得模块名称(对应的源文件名)。
特殊情况:当模块作为程序入口时,name__值是“__main__",我们可以根据这个特点,将模块源代码文件中的测试代码进行独立的处理。
"""本模块用于计算员工的薪资"""
company="北京尚学堂"
def yearSalary(monthSalary):
"""根据传入的月薪,计算出年薪"""
return monthSalary*12
def daySalary(monthSalary):
"""根据传入的月薪,计算出每天的xinz"""
return monthSalary/22.5
###################测试代码#############################
if __name__ =="__main__":
print(yearSalary(3000))
print(daySalary(3000))
5.模块文档字符串
我们可以通过__doc__可以获得模块的文档字符串的内容:
#读取模块中的文档字符串内容
import salary
print(salary.__doc__)
print(salary.yearSalary.__doc__)
二、模块的导入
1、import 语句导入
import 语句的基本语法格式如下:
import 模块名 #导入一个模块
import 模块 1,模块 2… #导入多个模块
import 模块名 as 模块别名 #导入模块并使用新名字
import 语句实现模块的导入和使用,import 本质上是使用了内置函数 __import__()。
2.from…import 导入
语法格式:
from 模块名 import 成员 1,成员 2,...
#使用from...import导入模块中指定的成员
from math import pi,sin
print(pi)
print(sin(pi/2))
模块中的所有成员: from 模块名 import *
它表示导入模块中所有的不 是以下划线(_)开头的名字都导入到当前位置,很有可能 会覆盖掉你之前已经定义的名字,且可读性极其的差,不推荐使用。
3.__import__()动态导入
import 语句本质上就是调用内置函数__import__(),我们可以通过它实现动态导入。给 __import__()动态传递不同的的参数值,就能导入不同的模块。
#使用__import__()动态导入指定的模块
s = "math"
m = __import__(s) #导入后生成的模块对象的引用给变量 m
print(m.pi)
note:一般不建议我们自行使用__import__()导入,其行为在 python2 和 python3 中 有差异,会导致意外错误。
一般情况下使用 importlib 模块来进行动态导入:
import importlib
a = importlib.import_module("math")
print(a.pi)
4. 模块的加载问题
一个模块无论导入多少次,这个模块在整个解释器进程内有且仅有一个实例对象。
#测试导入一个模块时,模块中的代码只会执行一次
import tes02 #tes02模块的语句会被执行
import tes02 #不会再执行 tes02 模块中的语句
#测试如何重新加载
print("#########################################")
import importlib
importlib.reload(tes02) #重新加载已执行过的模块
三、包的使用
1.概念
我们将功能类似的模块放到一起, 形成了“包”。本质上,“包”就是一个必须包含有__init__.py 的文件夹。包下面有模块,同样也可以包含“子包”,但是每个包中必须要有__init__.py 文件。
2.导入包的操作和本质
导入方法:
语法1:import item1,item2,... #item 必须是包或模块,不能是其他。
语法2:from package import item #package是包的名称,item 可以是包、模块,也可以是函数、 类、变量。
导入包的本质其实是“导入了包的__init__.py”文件。也就是说,”import pack1”意味 着执行了包 pack1 下面的__init__.py 文件。 这样,可以在__init__.py 中批量导入我们需要的模块,而不再需要一个个导入。
3.__init__.py 的三个核心作用:
1. 作为包的标识,不能删除。
2. 用来实现模糊导入
3. 导入包实质是执行__init__.py 文件,可以在__init__.py 文件中做这个包的初始化、以及 需要统一执行代码、批量导入。
#包的导入(以下3中方式调用时时的区别)
#import a.aa.module_AA
# a.aa.module_AA.fun_AA()
# from a.aa import module_AA
# module_AA.fun_AA()
# from a.aa.module_AA import fun_AA
# fun_AA()
###########################################################################3
# import a
# import math
# print(a.math.pi) #math模块已经在A包下的__init__.py中导入
# print(id(math)) #直接导入math和导入A.math对应同一个对象,两者ID相同
# print(id(a.math))
from a import * #模糊导入
module_A.fun_A() #module_A必须包含在A包__init__.py 的__all__变量中,否则会报错