使用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 pickle类库介绍(对象序列化和反序列化)
Nov 21 Python
Python遍历指定文件及文件夹的方法
May 09 Python
python实现的简单RPG游戏流程实例
Jun 28 Python
Linux中Python 环境软件包安装步骤
Mar 31 Python
浅谈numpy中linspace的用法 (等差数列创建函数)
Jun 07 Python
Python制作词云的方法
Jan 03 Python
使用TensorFlow-Slim进行图像分类的实现
Dec 31 Python
学python最电脑配置有要求么
Jul 05 Python
python如何将图片转换素描画
Sep 08 Python
Python机器学习算法之决策树算法的实现与优缺点
May 13 Python
Python进度条的使用
May 17 Python
Python字典和列表性能之间的比较
Jun 07 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运行环境配置的详解
2013/06/04 PHP
php数据类型判断函数有哪些
2013/09/23 PHP
async和DOM Script文件加载比较
2014/07/20 PHP
PHP如何根据文件头检测文件类型实例代码
2018/10/14 PHP
laravel-admin 管理平台获取当前登陆用户信息的例子
2019/10/08 PHP
Jquery事件的连接使用示例
2013/06/18 Javascript
jQuery的attr与prop使用介绍
2013/10/10 Javascript
简单谈谈jQuery(function(){})与(function(){})(jQuery)
2014/12/19 Javascript
js实现从中间开始往上下展开网页窗口的方法
2015/03/02 Javascript
javascript中去除数组重复元素的实现方法【实例】
2016/04/12 Javascript
用director.js实现前端路由使用实例
2017/01/27 Javascript
Node连接mysql数据库方法介绍
2017/02/07 Javascript
H5实现中奖记录逐行滚动切换效果
2017/03/13 Javascript
利用webstrom调试Vue.js单页面程序的方法教程
2017/06/06 Javascript
js实现鼠标拖拽多选功能示例
2017/08/01 Javascript
基于Datatables跳转到指定页的简单实例
2017/11/09 Javascript
vuex管理状态仓库使用详解
2020/07/29 Javascript
Python random模块常用方法
2014/11/03 Python
Python socket编程实例详解
2015/05/27 Python
Python中最大最小赋值小技巧(分享)
2017/12/23 Python
python实现图片文件批量重命名
2020/03/23 Python
python 脚本生成随机 字母 + 数字密码功能
2018/05/26 Python
Python补齐字符串长度的实例
2018/11/15 Python
Python解决pip install时出现的Could not fetch URL问题
2019/08/01 Python
pytorch 彩色图像转灰度图像实例
2020/01/13 Python
意大利奢华内衣制造商:Cosabella
2017/08/29 全球购物
Java Servlet API中forward() 与redirect()的区别
2014/04/20 面试题
监理资料员岗位职责
2014/01/03 职场文书
生物制药专业求职信
2014/03/11 职场文书
党的群众路线对照检查材料思想汇报(学校)
2014/10/04 职场文书
2014年法院工作总结
2014/11/24 职场文书
申请吧主发表的感言
2015/08/03 职场文书
导游词之湖州-太湖
2019/10/11 职场文书
Nginx四层负载均衡的配置指南
2021/06/11 Servers
python编程实现清理微信重复缓存文件
2021/11/01 Python
使用Ajax实现进度条的绘制
2022/04/07 Javascript