模块

3 阅读4分钟

image.png

python程序由模块构成,每个模块都对应一个.py文件,而每个.py文件都由语句构成。
程序复杂时,语句就多了,不方便管理。我们将实现同一个功能的语句封装 函数中,统一管理和调用,于是函数诞生了。
函数和语句多了,我们就将同一类型对象的“数据和行为”,也就是“变量和函数”,放到一起统一管理和调用,于是“类和对象”诞生了。
程序继续复杂,函数和类更加多了,我们就将实现类似功能的函数和类统统放到一个模块中,于是“模块”诞生了。 模块多了,我们就将实现类似功能的模块放到一起,于是“包” 就诞生了。

模块化编程

模块化编程将一个任务分解成多个模块每个模块就像一个积木一样,便于后期的反复使用、反复搭建。
优势:于将一个任务分解成多个模块,实现团队协同开发,完成大规模程序;实现代码复用。一个模块实现后,可以被反复调用;可维护性增强 流程:

  1. 设计API,进行功能描述
""" 本模块用于计算公司员工的薪资 """ 
company = "hhc" 

def yearSalary(monthSalary):    
    """根据传入的月薪,计算出年薪"""   
    pass 
def daySalary(monthSalary):    
    """根据传入的月薪,计算出每天的薪资"""    
    pass
  1. 编码实现API中描述的功能。
"""  
计算公司员工的薪资  
"""  
company = "hhc"  
def yearSalary(monthSalary):  
    """  
    根据月薪计算年薪  
    :param monthSalary: 月薪  
    :return: 年薪  
    """  
    return monthSalary*12  
  
def daySalary(monthSalary):  
    """  
    根据月薪计算日薪  
    :param monthSalary: 日薪  
    :return: 日薪  
    """  
    return monthSalary/22.5
  1. 在模块中编写测试代码,并消除全局代码
    每个模块都有一个名称,通过特殊变量 name 可以获取模块的名 称。在正常情况下,模块名字对应源文件名。仅有一个例外,就是当一个模块被作为程序入口时(主程序、交互式提示符下),它的 name 的值为 main
if __name__ =="__main__":  # 测试代码
    print(yearSalary(3000))  
    print(daySalary(3000))  
  1. 使用私有函数实现不被外部客户端调用的模块函数

模块的导入

import语句导入

import  模块名                   #导入一个模块 
import  模块1,模块2…            #导入多个模块 
import  模块名   as 模块别名     #导入模块并使用新 名字

通过import语句实现模块的导入和使用,import本质上是使用了内置函数 import()


import salary  
import math as m  
# print(salary.__doc__)  
# print(salary.yearSalary.__doc__)  
# print(salary.__name__)  
  
print(id(salary)) # 2362464582160  
print(type(salary)) # <class 'module'>  
  
print(m.sqrt(4)) # 2.0

from…import导入

# from 模块名 import 成员1,成员2,…

from math import pi,sin  
print(sin(pi/2)) # 1.0

__ import__() 动态导入

import语句本质上就是调用内置函数__ import__() ,我们可以通过它实现动态导入。给__import__() 动态传递不同的的参数值,就能导入不同的模块

s = "math" 
m = __import__(s)   #导入后生成的模块对象的引用给变量
m print(m.pi)

不推荐使用该方式,如果需要动态导入可以使 用 importlib 模块

import importlib  
a = importlib.import_module("math")  
print(a.pi) # 3.141592653589793

模块的加载问题

一般来说,模块中的内容只会被加载一次,如果再次导入该模块,模块中的内容将不会再执行一次。如果想要加载多次,可以使用importlib模块下的reload()方法。
import math
importlib.reload(math)

包的使用

本质上,“包”就是一个必须有 __ init__.py 的文件夹
image.png
a是上层的包,下面有一个子包: aa 。可以看到每个包里面都有 init.py文件。
在上面的结构中,我们可以用如下的方式引入包

# 方式一:
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()

导入包的本质其实是“导入了包的__init__.py ”文件。也就是说,import pack1意味着执行了包 pack1下面的__init__.py文件。 我们可以在__init__.py文件中选择我们要从该模块中导入的子模块

在该模块下的__init__.py文件中,列出需要导出的模块,当其他模块导入该模块时,默认提供如下的子模块
__all__=["module_A","module_A2"]