使用Python的package机制如何简化utils包设计详解


Posted in Python onDecember 11, 2017

package 机制

package是模块的集合,每一个Package的根目录下面都应当有一个__init__.py 文件。当解释器发现目录下有这个文件时,他就会认为这是一个Package,而不是一个普通的目录。

对于 package 机制的说明,其实官方文档已经有非常详尽的论述了,本文并不着眼于此。

简单来说,一个目录下如果包含 __init__.py ,则被 Python 视作一个 Python package。其中:

  • __init__.py 中的东西,在初始化这个包时,会首先被加载
  • package 中还可以定义 sub package

初衷

为了概念统一,我们把写代码的人,大致分为两种角色:

  • Library Author
  • Caller 即 API 使用者

有时候我们会是 1 或者 2, 有时候我们可能既是 1 又是 2 ( 比如负责一个较大的系统时)

很显然,本文的角度是从 1 出发的(即我们只扮演库作者,并且不知道我们的调用者是谁)。

最开始时,utils 可能仅仅是一个 utils.py 就可以了,然后调用者 from utils import XXUtils 就完事了,这自然没有本文什么事。

然而大部分情况不是这样的,所有 Utils 都放到一个文件里面是 stupid 的(一个源码文件最多 400~500行 )。所以我们的目录结构会是这样的:

utils/
 __init__.py
 a_util.py
 b_util.py
 ......

调用者怎么使用呢?from utils.a_util import AUtils

这种方式有一个假定:调用者要很清楚他所需要的 Utils 位于哪个 py 文件中。但是这种假定并不总是成立,大家对于同一概念的理解,极有可能是千差万别的。比如 utils,你觉得叫做 utils 合适,别人还觉得叫做 tools 合适呢,其实都是同一个东西。

显然,这加重了调用者的心智负担。更加显然的是,作为库作者,我们有义务来优化调用者的使用体验!(不然你的库再牛逼,没有人爱用也是空弹琴。)

HOW

合理利用 package 机制,就能马上优化这一体验。

我们只要在 __init__.py 中这么写即可:

__init__.py
from .a_util import AUtils
from .b_util import BUtils

调用者则仍然是这么使用:

from utils import AUtils, BUtils

即:调用者根本不关心你的实现在哪里,你只要给我一个 utils 的命名空间即可,而且确保所有的 Utils 都在这个命名空间里面。

为了更加符合 PEP8 的规范,作为库作者,我们的目录结构可能会变成这样:

utils/
 __init__.py
 _a_util.py    不对外界公开, 仅限本package的其他模块使用
 _b_util.py

应用

不仅是对于 utils 包,对与 constants 包,exceptions 包也可以应用此方法。在许多开源库中,大牛们经常使用这一手法来优化我们的体验(太常见了,几乎大部分开源库的 __init__.py 中都会写东西)

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python使用三角迭代计算圆周率PI的方法
Mar 20 Python
Python程序中用csv模块来操作csv文件的基本使用教程
Mar 03 Python
Python算法应用实战之队列详解
Feb 04 Python
numpy自动生成数组详解
Dec 15 Python
Python简单实现两个任意字符串乘积的方法示例
Apr 12 Python
Vue的el-scrollbar实现自定义滚动
May 29 Python
python获取命令行输入参数列表的实例代码
Jun 23 Python
对sklearn的使用之数据集的拆分与训练详解(python3.6)
Dec 14 Python
详解python中的线程与线程池
May 10 Python
python+selenium 点击单选框-radio的实现方法
Sep 03 Python
python中sklearn的pipeline模块实例详解
May 21 Python
Python学习笔记之装饰器
Aug 06 Python
python timestamp和datetime之间转换详解
Dec 11 #Python
Python时间戳使用和相互转换详解
Dec 11 #Python
python的exec、eval使用分析
Dec 11 #Python
Python中eval带来的潜在风险代码分析
Dec 11 #Python
Python验证文件是否可读写代码分享
Dec 11 #Python
Python文件操作基本流程代码实例
Dec 11 #Python
Python使用Turtle模块绘制五星红旗代码示例
Dec 11 #Python
You might like
这部好评如潮的动漫 知名梗频出 但是画风劝退很多人
2020/03/08 日漫
德生PL990的分析评价
2021/03/02 无线电
php防止恶意刷新与刷票的方法
2014/11/21 PHP
php将textarea数据提交到mysql出现很多空格的解决方法
2014/12/19 PHP
JS 用6N±1法求素数 实例教程
2009/10/20 Javascript
详谈 Jquery Ajax异步处理Json数据.
2011/09/09 Javascript
关于extjs4如何获取grid修改后的数据的问题
2013/08/07 Javascript
JS中引用百度地图并将百度地图的logo和信息去掉
2013/09/29 Javascript
js中substr,substring,indexOf,lastIndexOf的用法小结
2013/12/27 Javascript
js实现宇宙星空背景效果的方法
2015/03/03 Javascript
使用JavaScript实现连续滚动字幕效果的方法
2015/07/07 Javascript
原生js模拟淘宝购物车项目实战
2015/11/18 Javascript
jquery利用拖拽方式在图片上添加热链接
2015/11/24 Javascript
JavaScript知识点总结之如何提高性能
2016/01/15 Javascript
jquery easyui DataGrid简单示例
2017/01/23 Javascript
jQuery插件HighCharts实现的2D条状图效果示例【附demo源码下载】
2017/03/15 Javascript
Vue编写多地区选择组件
2017/08/21 Javascript
vue导出html、word和pdf的实现代码
2018/07/31 Javascript
vue.js编译时给生成的文件增加版本号
2018/09/17 Javascript
JavaScript实现沿五角星形线摆动的小圆实例详解
2020/07/28 Javascript
sqlalchemy对象转dict的示例
2014/04/22 Python
Python去除列表中重复元素的方法
2015/03/20 Python
分享一个简单的python读写文件脚本
2017/11/25 Python
pyqt5 实现多窗口跳转的方法
2019/06/19 Python
python3模拟实现xshell远程执行liunx命令的方法
2019/07/12 Python
详解Python 重学requests发起请求的基本方式
2020/02/07 Python
浅谈Python3多线程之间的执行顺序问题
2020/05/02 Python
关于tf.matmul() 和tf.multiply() 的区别说明
2020/06/18 Python
浅谈tensorflow 中的图片读取和裁剪方式
2020/06/30 Python
HTML5中使用json对象的实例代码
2018/09/10 HTML / CSS
关于Java finally的面试题
2016/04/27 面试题
高级护理专业毕业生推荐信
2013/12/25 职场文书
高中考试作弊检讨书
2014/01/14 职场文书
课外科技活动总结
2014/08/27 职场文书
解除劳动合同协议书(样本)
2014/10/02 职场文书
JS创建或填充任意长度数组的小技巧汇总
2021/10/24 Javascript