使用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实现简单登录验证
Apr 13 Python
浅析python3字符串格式化format()函数的简单用法
Dec 07 Python
Python实现的字典排序操作示例【按键名key与键值value排序】
Dec 21 Python
python 通过SSHTunnelForwarder隧道连接redis的方法
Feb 19 Python
基于Django框架的权限组件rbac实例讲解
Aug 31 Python
对tensorflow 中tile函数的使用详解
Feb 07 Python
python不到50行代码完成了多张excel合并的实现示例
May 28 Python
opencv 图像滤波(均值,方框,高斯,中值)
Jul 08 Python
如何教少儿学习Python编程
Jul 10 Python
python属于哪种语言
Aug 16 Python
DRF使用simple JWT身份验证的实现
Jan 14 Python
Python机器学习之PCA降维算法详解
May 19 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/03 日漫
认识并使用PHP超级全局变量
2010/01/26 PHP
PHP中如何调用webservice的实例参考
2013/04/25 PHP
PHP7之Mongodb API使用详解
2015/12/26 PHP
Yii2 GridView实现列表页直接修改数据的方法
2016/05/16 PHP
有关PHP 中 config.m4 的探索
2020/08/26 PHP
Jquery 快速构建可拖曳的购物车DragDrop
2009/11/30 Javascript
关于js注册事件的常用方法
2013/04/03 Javascript
JS增加行复制行删除行的实现代码
2013/11/09 Javascript
js调用百度地图及调用百度地图的搜索功能
2015/09/07 Javascript
JavaScript实现ASC转汉字及汉字转ASC的方法
2016/01/23 Javascript
详解JavaScript中双等号引起的隐性类型转换
2016/05/30 Javascript
jQuery原理系列-css选择器的简单实现
2016/06/07 Javascript
在js中实现邮箱格式的验证方法(推荐)
2016/10/24 Javascript
详解Vue 方法与事件处理器
2017/06/20 Javascript
基于jquery实现多级菜单效果
2017/07/25 jQuery
浅谈vue首屏加载优化
2018/06/28 Javascript
js中switch语句的学习笔记
2020/03/25 Javascript
解决antd的Form组件setFieldsValue的警告问题
2020/10/29 Javascript
Ant Design Vue table中列超长显示...并加提示语的实例
2020/10/31 Javascript
多线程爬虫批量下载pcgame图片url 保存为xml的实现代码
2013/01/17 Python
Python函数式编程指南(四):生成器详解
2015/06/24 Python
Swift中的协议(protocol)学习教程
2016/07/08 Python
Python用list或dict字段模式读取文件的方法
2017/01/10 Python
python itchat实现微信好友头像拼接图的示例代码
2017/08/14 Python
python中int与str互转方法
2018/07/02 Python
详解Python3 基本数据类型
2019/04/19 Python
python对Excel按条件进行内容补充(推荐)
2019/11/24 Python
Win10下安装并使用tensorflow-gpu1.8.0+python3.6全过程分析(显卡MX250+CUDA9.0+cudnn)
2020/02/17 Python
python自动脚本的pyautogui入门学习
2020/04/01 Python
HTML5 表单验证失败的提示语问题
2017/07/13 HTML / CSS
美国最大的船只买卖在线市场:Boat Trader
2018/08/04 全球购物
安全生产专项整治方案
2014/05/06 职场文书
群众路线教育实践活动个人对照检查材料思想汇报(社区班子)
2014/10/06 职场文书
财务工作个人总结
2015/02/27 职场文书
关于mysql中string和number的转换问题
2022/06/14 MySQL