使用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实现获取网站PR及百度权重
Jan 21 Python
Django1.7+python 2.78+pycharm配置mysql数据库
Oct 09 Python
TensorFlow安装及jupyter notebook配置方法
Sep 08 Python
django2用iframe标签完成网页内嵌播放b站视频功能
Jun 20 Python
关于pandas的离散化,面元划分详解
Nov 22 Python
pytorch::Dataloader中的迭代器和生成器应用详解
Jan 03 Python
python通过移动端访问查看电脑界面
Jan 06 Python
pytorch加载自定义网络权重的实现
Jan 07 Python
pycharm中导入模块错误时提示Try to run this command from the system terminal
Mar 26 Python
如何从csv文件构建Tensorflow的数据集
Sep 21 Python
python获取linux系统信息的三种方法
Oct 14 Python
python自动化八大定位元素讲解
Jul 09 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
虹吸式咖啡壶操作
2021/03/03 冲泡冲煮
PHP+SQL 注入攻击的技术实现以及预防办法
2011/01/27 PHP
php数组函数序列之array_combine() - 数组合并函数使用说明
2011/10/29 PHP
php 模拟GMAIL,HOTMAIL(MSN),YAHOO,163,126邮箱登录的详细介绍
2013/06/18 PHP
php实现将HTML页面转换成word并且保存的方法
2016/10/14 PHP
php魔术方法功能与用法实例分析
2016/10/19 PHP
Zend Framework过滤器Zend_Filter用法详解
2016/12/09 PHP
PHP微信企业号开发之回调模式开启与用法示例
2017/11/25 PHP
js 点击按钮弹出另一页,选择值后,返回到当前页
2010/05/26 Javascript
jQuery实现倒计时按钮功能代码分享
2014/09/03 Javascript
js实现头像图片切割缩放及无刷新上传图片的方法
2015/07/17 Javascript
js实现TAB切换对应不同颜色的代码
2015/08/31 Javascript
EasyUI中的dataGrid的行内编辑
2017/06/22 Javascript
AngularJS实现注册表单验证功能
2017/10/16 Javascript
Angular2实现组件交互的方法分析
2017/12/19 Javascript
vue使用 better-scroll的参数和方法详解
2018/01/25 Javascript
java遇到微信小程序 "支付验证签名失败" 问题解决
2019/12/22 Javascript
JS面向对象编程实现的Tab选项卡案例详解
2020/03/03 Javascript
JS定时器如何实现提交成功提示功能
2020/06/12 Javascript
[18:16]sakonoko 2017年卡尔集锦
2018/02/06 DOTA
让 python 命令行也可以自动补全
2014/11/30 Python
Python Web框架Tornado运行和部署
2020/10/19 Python
python字典多键值及重复键值的使用方法(详解)
2016/10/31 Python
利用Python暴力破解zip文件口令的方法详解
2017/12/21 Python
对python中Matplotlib的坐标轴的坐标区间的设定实例讲解
2018/05/25 Python
Python里字典的基本用法(包括嵌套字典)
2019/02/27 Python
Python基于paramunittest模块实现excl参数化
2020/04/26 Python
The Hut美国/加拿大:英国领先的豪华在线百货商店
2019/03/26 全球购物
英国领先的体验日提供商:Buyagift
2019/04/19 全球购物
我想声明一个指针并为它分配一些空间, 但却不行。这些代码有什么 问题?char *p; *p = malloc(10);
2016/10/06 面试题
出纳岗位职责
2013/11/09 职场文书
法人授权委托书
2014/04/03 职场文书
领导班子整改措施
2014/10/24 职场文书
呐喊读书笔记
2015/06/30 职场文书
教师节简报
2015/07/20 职场文书
MySQL性能压力基准测试工具sysbench的使用简介
2021/04/21 MySQL