使用Python的package机制如何简化utils包设计详解
作者:hezhiming 发布时间:2021-08-14 04:21:06
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 中都会写东西)
来源:https://juejin.im/post/5a2cfc4f6fb9a044ff316588


猜你喜欢
- HTML实体符号被用作实现保留字符(reserved characters)或者表达键盘无法输入的一些常用字符。在大多数浏览器中默认的字符集
- python中有的df列比较长head的时候会出现省略号,现在数据分析常用的就是基于anaconda的notebook和sypder,在sp
- 在OOCSS中怎么定义“对象”?对象类似JAVA中的类,保持着OO的特征。一个CSS对象由4部分组成:可能是一个或多个DOM节点的HTML由
- 关于树莓派四驱小车的运动方向控制、摄像头方向控制已经在前面的两篇博文中介绍过。有需要的可以参考。本文也是基于上述两个python文件就绪的情
- 笔者在网上找了很多关于VSCODE配置Go语言的教程,但是由于版本等种种问题,最终都已失败告终。无奈只能在官方文档上寻求帮助,现在终于可以了
- 具体代码如下所述:#coding=utf-8import itchatfrom itchat.content import TEXTfrom
- 本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。以下文章来源于Pyth
- 测试环境 硬件:CPU 酷睿双核T5750 内存:2G 软件:Windows server 2003 + sql server 2005 O
- 接着上篇的内容,这里实现一个交易记录链,废话不多说,先看图:跟之前的逻辑类似,但也有少许不同,这里多了一个payloadhash,以及对pa
- 使用方法和步骤如下:step1检测是否已经启用ServiceBroker,检测方法:SelectDATABASEpRoPERTYEX(
- 一、 技术要点 我们都知道Windows应用程序在运行时会启动一个进程,其总包括若干线程,不同的进程之间通信是开发分布
- 想到TDE(Transparent Data Encryption)。 TDE MSDN 说明: “透明数据加密”(TDE) 可对数据和日志
- 互联网是一个飞速发展的行业,任何的止步不前都会导致被淘汰,只是时间早晚的问题,所以一个公司的学习与创新能力是非常重要的,特别是对于一个年轻的
- 如下所示:matplotlib.pyplot.plot(*args, **kwargs)绘制线条或标记的轴。参数是一个可变长度参数,允许多个
- 1.线性与非线性回归线性回归 Linear Regression:两个变量之间的关系是一次函数关系的—&mdas
- insert into values插入多条数据insert into 表名(字段名1,字段名2)values(值a1,值b1), (值a2
- 起步在 《分布式任务队列Celery使用说明》 中介绍了在 Python 中使用 Celery 来实验异步任务和定时任务功能。本文介绍如何在
- 一、协程官方描述;协程是子例程的更一般形式。 子例程可以在某一点进入并在另一点退出。 协程则可以在许多不同的点上进入、退出和恢复。 它们可通
- asp使用WScript.Shell获取电脑的网络配置信息Option Explicit Dim WSHShe
- 1.Jinja21.简介Jinja2是Python下一个被广泛应用的模版引擎,他的设计思想来源于Django的模板引擎,并扩展了其语法和一系