使用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中的并发编程实例
Jul 07 Python
python使用urlparse分析网址中域名的方法
Apr 15 Python
Python入门之三角函数全解【收藏】
Nov 08 Python
Python之dict(或对象)与json之间的互相转化实例
Jun 05 Python
python实现对csv文件的列的内容读取
Jul 04 Python
python一键去抖音视频水印工具
Sep 14 Python
pytorch 可视化feature map的示例代码
Aug 20 Python
matplotlib实现显示伪彩色图像及色度条
Dec 07 Python
pytorch下大型数据集(大型图片)的导入方式
Jan 08 Python
浅析Python 责任链设计模式
Sep 11 Python
Python中的流程控制详解
Feb 18 Python
教你如何用Python实现人脸识别(含源代码)
Jun 23 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
PHP中CURL方法curl_setopt()函数的参数分享
2013/01/19 PHP
Codeigniter生成Excel文档的简单方法
2014/06/12 PHP
php使用Jpgraph绘制3D饼状图的方法
2015/06/10 PHP
编写PHP脚本使WordPress的主题支持Widget侧边栏
2015/12/14 PHP
thinkphp3.2实现上传图片的控制器方法
2016/04/28 PHP
PHP中str_split()函数的用法讲解
2019/04/11 PHP
ExtJS 2.0实用简明教程 之Border区域布局
2009/04/29 Javascript
基于jquery的获取mouse坐标插件的实现代码
2010/04/01 Javascript
js解析与序列化json数据(一)json.stringify()的基本用法
2013/02/01 Javascript
深入理解JSON数据源格式
2014/01/10 Javascript
Javascript 中创建自定义对象的方法汇总
2014/12/04 Javascript
JavaScript中定义函数的三种方法
2015/03/12 Javascript
基于jQuery实现搜索关键字自动匹配功能
2020/03/26 Javascript
Spring mvc 接收json对象
2015/12/10 Javascript
js canvas实现擦除动画
2016/07/16 Javascript
判断js的Array和Object的实现方法
2016/08/29 Javascript
jQuery插件ImgAreaSelect实现头像上传预览和裁剪功能实例讲解一
2017/05/26 jQuery
jackson解析json字符串,首字母大写会自动转为小写的方法
2017/12/22 Javascript
AngularJS双向数据绑定原理之$watch、$apply和$digest的应用
2018/01/30 Javascript
JS 实现缓存算法的示例(FIFO/LRU)
2018/03/20 Javascript
前后端如何实现登录token拦截校验详解
2018/09/03 Javascript
详解angularjs跨页面传参遇到的一些问题
2018/11/01 Javascript
vue返回上一页面时回到原先滚动的位置的方法
2018/12/20 Javascript
详解JS浏览器事件循环机制
2019/03/27 Javascript
[58:46]OG vs NAVI 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
python中文件变化监控示例(watchdog)
2017/10/16 Python
python3调用百度翻译API实现实时翻译
2018/08/16 Python
python模拟菜刀反弹shell绕过限制【推荐】
2019/06/25 Python
django框架两个使用模板实例
2019/12/11 Python
Python中logging日志记录到文件及自动分割的操作代码
2020/08/05 Python
详解canvas drawImage()方法绘制图片不显示的问题
2018/10/08 HTML / CSS
党支部特色活动方案
2014/08/20 职场文书
个人三严三实对照检查材料
2014/09/25 职场文书
英文慰问信
2015/02/14 职场文书
2015年征兵工作总结
2015/07/23 职场文书
JS精髓原型链继承及构造函数继承问题纠正
2022/06/16 Javascript