使用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条件和循环的使用方法
Nov 01 Python
Python 自动化表单提交实例代码
Jun 08 Python
Django数据库操作的实例(增删改查)
Sep 04 Python
教你学会使用Python正则表达式
Sep 07 Python
Python使用文件锁实现进程间同步功能【基于fcntl模块】
Oct 16 Python
itchat接口使用示例
Oct 23 Python
Python实现的摇骰子猜大小功能小游戏示例
Dec 18 Python
python3爬虫怎样构建请求header
Dec 23 Python
python简单鼠标自动点击某区域的实例
Jun 25 Python
python requests更换代理适用于IP频率限制的方法
Aug 21 Python
Python sep参数使用方法详解
Feb 12 Python
python 实现"神经衰弱"翻牌游戏
Nov 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
MYSQL数据库初学者使用指南
2006/11/16 PHP
PHP及Zend Engine的线程安全模型分析
2011/11/10 PHP
比较详细PHP生成静态页面教程
2012/01/10 PHP
再推荐十款免费的php开发工具
2015/11/09 PHP
PHP数组函数array_multisort()用法实例分析
2016/04/02 PHP
PHP面向对象继承用法详解(优化与减少代码重复)
2016/12/02 PHP
PHP调用微博接口实现微博登录的方法示例
2018/09/22 PHP
基于jquery的跨域调用文件
2010/11/19 Javascript
Extjs NumberField后面加单位实现思路
2013/07/30 Javascript
js实现透明度渐变效果的方法
2015/04/10 Javascript
JS实现漂亮的淡蓝色滑动门效果代码
2015/09/23 Javascript
jquery实现倒计时效果
2015/12/14 Javascript
JavaScript中的普通函数和箭头函数的区别和用法详解
2017/03/21 Javascript
微信小程序 下拉菜单简单实例
2017/04/13 Javascript
解决JavaScript layui 下拉框不显示的问题
2018/08/14 Javascript
swiper在vue项目中loop循环轮播失效的解决方法
2018/09/15 Javascript
vue2.x 对象劫持的原理实现
2020/04/19 Javascript
Python中的is和id用法分析
2015/01/26 Python
Python类的定义、继承及类对象使用方法简明教程
2015/05/08 Python
详解Python中的Numpy、SciPy、MatPlotLib安装与配置
2017/11/17 Python
Python学习之Anaconda的使用与配置方法
2018/01/04 Python
python使用matplotlib画饼状图
2018/09/25 Python
Python selenium根据class定位页面元素的方法
2019/02/26 Python
利用Python+阿里云实现DDNS动态域名解析的方法
2019/04/01 Python
Python如何将字符串转换为日期
2020/07/31 Python
python安装第三方库如xlrd的方法
2020/10/31 Python
Python爬虫自动化获取华图和粉笔网站的错题(推荐)
2021/01/08 Python
公司前台接待岗位职责
2013/12/03 职场文书
餐厅筹备计划书
2014/04/25 职场文书
博士生求职信
2014/07/06 职场文书
民主评议党员自我评价材料
2014/09/18 职场文书
夫妻忠诚协议范文
2014/11/16 职场文书
2019开业庆典剪彩仪式主持词!
2019/07/22 职场文书
使用 Apache Superset 可视化 ClickHouse 数据的两种方法
2021/07/07 Servers
Redis 哨兵机制及配置实现
2022/03/25 Redis
python神经网络学习 使用Keras进行回归运算
2022/05/04 Python