写点什么

python 小知识 - 模块

作者:AIWeker
  • 2022-11-15
    福建
  • 本文字数:2639 字

    阅读完需:约 9 分钟

1.什么是模块

在《失控》中提到一个几千万行的程序(操作系统)要想没有 bug 是很难,减少 bug 的解决方案就是不断的拆分功能项,直到不能拆分为止,只要保证拆分的最小功能项通过一定的单元测试,就可能消费 bug(当然还有集成性和系统性的 bug)。《失控》里说的就是现代软件工程的模块化开发方式,在面向对象开发以及架构设计上都会涉及到。


那什么是模块?从上面可知,模块可以理解为独立的功能拆分,可根据具体业务拆分成大模块和小模块。


举几个例子:


一个入库系统可以拆分成前端的展示模块,后端的业务处理以及中间的交互层;后端业务处理可以拆分成数据处理(如数据库操作等)和具体的不同的业务模块(如计费模块,折扣模块,物料模块等);


一个深度学习的训练可以拆分:


  • 数据模块:负责处理和加载数据

  • 网络模块:负责构建深度学习网络

  • 训练模块:负责调用数据、构建网络以及设计损失和优化器,以及梯度方向传播,还有模型参数的保存和加载等

  • 测试推理模块:负责模型测试和推理

  • 功能模块:比如常见的 utils


以上可能是比较大的模块,还可以细分成更细的小的模块;


  • 比如数据模块,可以拆分成小的特定数据的模块,比如不同的数据集的解析不同,可以构建不同的数据集模块和以及可能的数据处理模块(如数据增强);

  • 网络模块,可以拆分成不同类型的网络等


可想而知,模块和模块之间是存在引用的关系,设计时要尽可能做到松耦合,能更友好的变更,如果一次变更需要修改大部分的代码,可以考虑下是否做到合理的模块化设计。


总结一下:


  • 模块是功能的划分,是软件程序的架构设计

  • 模块化是减少 bug 的有效途径

  • 可以适当的模块化,也不要过度模块化,看功能的复杂性,越复杂就有必要拆分的更细

  • 千万不要把所有代码都写到一个文件哦!

  • 模块不要相互引用

  • 如果你听到别人说什么数据层,业务层,xx 层,你可以理解为就是模块

2.python 中模块

python 中模块可以分为 2 个:


  • 一个 python 的.py 文件,真正的处理功能的模块,可以是公共变量、函数以及类等

  • 对模块的逻辑划分即,通过目录层级的方式来管理模块,python 是通过 package 包的方式来实现的;


一个简单的 python 模块设计:包括主程序 main.py,模块 model 和两个 package 包(data/utils)


./├── main.py├── model.py├── data│   ├── dataset.py│   ├── __init__.py├── utils│   ├── utils.py│   ├── __init__.py
复制代码


我们先来看下,和主程序平级的模块的调用,model.py 如下包括变量、函数和类等:


  • model.py


    test = 1
def func(): print('this is func in model.py') class Cls(object): def __init__(self, a): print('init {}'.format(a)) self.a = a def process_a(self): return self.a + 1
复制代码


  • 调用


    import model    print(model.test)    model.func()    cls = model.Cls(1)    print(cls.process_a())
# 1 # this is func in model.py # init 1 # 2
复制代码


从上可知,模块是通过import进行导入, 并通过模块名+.的方式调用;


import 可以有不同的方式:


  • 导入整个模块: import model

  • 导入模块内的元素: import model.func as func

  • 通过 from 方式: from model import func


不过,强烈建议按导入整个模块的方式,避免多个模块相互冲突;比如模块 A 和模块 B 都要 func,如果通过 from 方式导入,最终 func 混淆,实际为后导入的 func 的功能,除非你又进行 as 重命名


接着,我们来看下包里模块的调用;我们知道包是同步目录的方式来管理模块,那如何区分目录和包?


是的,python 是通过目录下添加__init__.py 文件(可以是空的),来使得正常目录变成包。


import data.dataset as datasetprint(dataset.test)dataset.data_func()cls = dataset.DCls(1)print(cls.process_a())
复制代码


包下模块的调用,在 import 时需要带上包名,其他和正常的包一样。


包中模块的导入和目录路径一样,可以分为相对导入和绝对导入


  • data.dataset是绝对导入

  • from ..data import dataset as dataset 是相对导入(比如在 utils 中引用 dataset), .表示当前路径,..表示上一级目录,一次类推


不建议相对导入

2.1python 如何寻找模块

我们一般是通过pip install方式来安装第三方的包,安装完在程序里直接通过import就可以直接调用模块的功能,而这些包和模块并不是我们的程序的同级目录,一个问题是 python 解释器是如何正确找到这些包和模块?


python 解释器搜索模块范围和优先级如下:


  • 1.当前目录

  • 2.PYTHONPATH 环境变量目录

  • 3.安装 Python 时配置的与安装相关的目录


安装第三方的包是属于第 3 种的情况下,一般是你的 python 目录或者虚拟环境目录。


所以说自己建立的模块名不要和第三方模块相同,否则你 import 的时候按照顺序你导入时自己的模块,而不是第三方的模块。了解了这个可以避免自己都觉得不可解释的问题。


对于模块,我们经常会遇到模块找不到的问题: ModuleNotFoundError: No module named 'data.dataseta'可以检查下:


  • 模块的包和模块名是否正确

  • 如果 1 正确情况,python 是否能够搜索到模块,可以通过查看sys.path看下是否包含你需要的模块


以下为本地的 python 包搜索范围:


['', 'D:\\Programs\\anaconda3\\python36.zip', 'D:\\Programs\\anaconda3\\DLLs', 'D:\\Programs\\anaconda3\\lib', 'D:\\Programs\\anaconda3', 'D:\\Programs\\anaconda3\\lib\\site-packages', 'D:\\Programs\\anaconda3\\lib\\site-packages\\win32', 'D:\\Programs\\anaconda3\\lib\\site-packages\\win32\\lib', 'D:\\Programs\\anaconda3\\lib\\site-packages\\Pythonwin', 'D:\\Programs\\anaconda3\\lib\\site-packages\\IPython\\extensions']
复制代码


如果sys.path没有包含,可以手动添加的方式将目录添加到sys.path中,如:



import os, sys
cur_path = os.path.abspath(os.path.dirname(__file__))sys.path.append(cur_path)
复制代码


当前你可以直接修改 PYTHONPATH 环境量,linux 中为export PYTHONPATH="./"

3.模块内置方法

python 为每个模块提供了内置方法,如果遇到无法解释的现象可以看看这些方法,判断是否调用了正确的模块


  • file 提供__file__ 获取模块路径

  • name 模块名

  • package 包名

  • dir()内置函数返回包含模块定义的名称的字符串的排序


print(model.__file__)print(dataset.__package__)print(model.__name__)print(dir(model))# D:\mywork\notebook\model.py# data# model# ['Cls', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'func', 'test']
复制代码


发布于: 刚刚阅读数: 3
用户头像

AIWeker

关注

InfoQ签约作者 / 公众号:人工智能微客 2019-11-21 加入

人工智能微客(aiweker)长期跟踪和分享人工智能前沿技术、应用、领域知识,不定期的发布相关产品和应用,欢迎关注和转发

评论

发布
暂无评论
python小知识-模块_Python_AIWeker_InfoQ写作社区