使用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 相关文章推荐
可用于监控 mysql Master Slave 状态的python代码
Feb 10 Python
python处理文本文件并生成指定格式的文件
Jul 31 Python
Fiddler如何抓取手机APP数据包
Jan 22 Python
Python实现的FTP通信客户端与服务器端功能示例
Mar 28 Python
Python下简易的单例模式详解
Apr 08 Python
Python内置random模块生成随机数的方法
May 31 Python
用Python实现二叉树、二叉树非递归遍历及绘制的例子
Aug 09 Python
如何基于Python实现自动扫雷
Jan 06 Python
python global和nonlocal用法解析
Feb 03 Python
详谈tensorflow gfile文件的用法
Feb 05 Python
Python smtp邮件发送模块用法教程
Jun 15 Python
解决Pymongo insert时会自动添加_id的问题
Dec 05 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与XML联手进行网站编程代码实例
2008/07/10 PHP
php生成随机密码的三种方法小结
2010/09/04 PHP
php生成excel列序号代码实例
2013/12/24 PHP
php测试kafka项目示例
2020/02/06 PHP
juqery 学习之三 选择器 简单 内容
2010/11/25 Javascript
jquery的map与get方法详解
2013/11/04 Javascript
js数组去重的常用方法总结
2014/01/24 Javascript
兼容IE、firefox以及chrome的js获取时间(getFullYear)
2014/07/04 Javascript
基于jQuery的图片不完全按比例自动缩小
2014/07/11 Javascript
jQuery中:image选择器用法实例
2015/01/03 Javascript
Jquery插件实现点击获取验证码后60秒内禁止重新获取
2015/03/13 Javascript
jQuery实现的向下图文信息滚动效果
2015/05/03 Javascript
7个有用的jQuery代码片段分享
2015/05/19 Javascript
果断收藏9个Javascript代码高亮脚本
2016/01/06 Javascript
noty ? jQuery通知插件全面解析
2016/05/18 Javascript
微信小程序 火车票查询实例讲解
2016/10/17 Javascript
探究JavaScript中的五种事件处理程序方式
2016/12/07 Javascript
select下拉框插件jquery.editable-select详解
2017/01/22 Javascript
详解JavaScript 中getElementsByName在IE中的注意事项
2017/02/21 Javascript
在Js页面通过POST传递参数跳转到新页面详解
2017/08/25 Javascript
Bootstrap 实现表格样式、表单布局的实例代码
2018/12/09 Javascript
React-redux实现小案例(todolist)的过程
2019/09/29 Javascript
web.py中调用文件夹内模板的方法
2014/08/26 Python
python 剪切移动文件的实现代码
2018/08/02 Python
解决python os.mkdir创建目录失败的问题
2018/10/16 Python
150行python代码实现贪吃蛇游戏
2020/04/24 Python
python 基于selectors库实现文件上传与下载
2020/12/31 Python
台湾屈臣氏网路商店:Watsons台湾
2020/12/29 全球购物
xml有哪些解析技术?区别是什么
2016/04/26 面试题
linux比较文件内容的命令是什么
2015/09/23 面试题
外贸业务员求职信范文
2013/12/12 职场文书
社区科普工作方案
2014/06/03 职场文书
企业2014年度工作总结
2014/12/10 职场文书
巴黎圣母院观后感
2015/06/10 职场文书
2016入党心得体会范文
2016/01/06 职场文书
Spring Bean的实例化之属性注入源码剖析过程
2021/06/13 Java/Android