使用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写的ARP攻击代码实例
Jun 04 Python
Python下的subprocess模块的入门指引
Apr 16 Python
使用Python对IP进行转换的一些操作技巧小结
Nov 09 Python
Python简单网络编程示例【客户端与服务端】
May 26 Python
Python编程实现粒子群算法(PSO)详解
Nov 13 Python
Python实现读取SQLServer数据并插入到MongoDB数据库的方法示例
Jun 09 Python
对Python subprocess.Popen子进程管道阻塞详解
Oct 29 Python
详解pandas如何去掉、过滤数据集中的某些值或者某些行?
May 15 Python
python实现简单坦克大战
Mar 27 Python
Python如何对XML 解析
Jun 28 Python
解决TensorFlow程序无限制占用GPU的方法
Jun 30 Python
Python 如何实现文件自动去重
Jun 02 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
与空气斗智斗勇的经典《Overlord》,传说中的“无稽之谈”
2020/04/09 日漫
PHP实现的折半查找算法示例
2017/12/19 PHP
Thinkphp5行为使用方法汇总
2017/12/21 PHP
PHP+jQuery+Ajax实现多图片上传效果
2015/03/14 Javascript
javascript模拟php函数in_array
2015/04/27 Javascript
Javascript递归打印Document层次关系实例分析
2015/05/15 Javascript
实例代码详解jquery.slides.js
2015/11/16 Javascript
Vue-resource实现ajax请求和跨域请求示例
2017/02/23 Javascript
基于vue cli重构多页面脚手架过程详解
2018/01/23 Javascript
浅谈Vue Element中Select下拉框选取值的问题
2018/03/01 Javascript
vue用递归组件写树形控件的实例代码
2018/07/19 Javascript
如何使用vuex实现兄弟组件通信
2018/11/02 Javascript
用element的upload组件实现多图片上传和压缩的示例代码
2019/02/12 Javascript
JS实现指定区域的全屏显示功能示例
2019/04/25 Javascript
解决LayUI加上form.render()下拉框和单选以及复选框不出来的问题
2019/09/27 Javascript
微信小程序 scroll-view的使用案例代码详解
2020/06/11 Javascript
[02:23]2014DOTA2国际邀请赛中国战队回顾
2014/08/01 DOTA
Python中使用dom模块生成XML文件示例
2015/04/05 Python
python 简单的绘图工具turtle使用详解
2017/06/21 Python
浅谈python的输入输出,注释,基本数据类型
2019/04/02 Python
浅谈Python3实现两个矩形的交并比(IoU)
2020/01/18 Python
Django模板获取field的verbose_name实例
2020/05/19 Python
CSS去掉A标签(链接)虚线框的方法
2014/04/01 HTML / CSS
Origins悦木之源英国官网:雅诗兰黛集团高端植物护肤品牌
2017/11/06 全球购物
AVI-8手表美国官方商店:AVI-8 USA
2019/04/10 全球购物
巴黎欧莱雅法国官网:L’Oreal Paris
2019/04/30 全球购物
高中生学习生活的自我评价
2013/11/27 职场文书
学院书画协会部门岗位职责
2013/12/01 职场文书
岗位说明书范文
2014/05/07 职场文书
干部竞争上岗演讲稿
2014/09/11 职场文书
银行领导班子四风对照检查材料
2014/09/27 职场文书
自愿离婚协议书2015
2015/01/26 职场文书
热血教师观后感
2015/06/10 职场文书
创业计划书之旅游网站
2019/09/06 职场文书
详解Javascript实践中的命令模式
2021/05/05 Javascript
win10电脑关机快捷键是哪个 win10快速关机的几种方法
2022/08/14 数码科技