【遇见Python】Define、Module、Package(part III)

124 阅读2分钟

引言

前两篇文章,从一个引用报错,聊到了其解决方案,并引出了Define、Module、Package相关概念。然后对Define、Module做了深入探索。

本篇文章,我们来继续探索下Package

正文

Package

Package是一种,将一个或多个Module组织起来的方法,使它们更容易组织到逻辑组中。

Package还允许我们将Module组织到不同的文件夹中。如果你发现自己有多个Module,那么是时候使用Package了。

本文不包括分发包的相关内容。如果想了解更多关于包分发的信息,请查看 Python Wheels 的文档页面。

一个Package,就是一个带有 _init_.py 文件和一个或多个Module的目录。 _init_.py 文件是标志,告诉 Python 这是一个Package,也是执行初始化代码的地方。

.
└── src/
    ├── main.py
    └── utils/
        ├── __init__.py
        └── util.py

41CF5442.png 上面这个例子中,utils就是一个Package。即使_init_.py文件是个空文件也没问题,这个文件只是为了标记文件夹是个Package而已。

一个Package,可以有多个Module:

.
└── src/
    ├── main.py
    └── utils/
        ├── __init__.py
        ├── util.py
        └── otherUtil.py

一个文件夹下,可以有多个Package:

.
└── src/
    ├── main.py
    ├── utils/
    │   ├── __init__.py
    │   ├── util.py
    │   └── otherUtil.py
    └── calculations/
        ├── __init__.py
        └── financials.py

甚至可以有网状Package:

.
└── src/
    ├── main.py
    ├── utils/
    │   ├── __init__.py
    │   ├── util.py
    │   └── shared/
    │       ├── __init__.py
    │       └── helpers.py
    └── calculations/
        ├── __init__.py
        └── financials.py

Package可以像Module一样导入,但是Package内的相对导入,是有一点小棘手的。

.
└── src/
    ├── main.py
    └── utils/
        ├── __init__.py
        ├── util.py
        └── shared/
            ├── __init__.py
            └── helpers.py
# main.py
import utils.util

print("About to do something cool!")
utils.util.doSomethingCool()
# util.py
from . shared import helpers

def doSomethingCool():
    print(helpers.doHelp("Doing something cool"))

为什么这里可以用. shared做相对导入?因为util.py文件和shared Package在同一个父Package中。只有在相同Package中的东西,可以使用相对导入

# helpers.py

def doHelp(x):
    return "help {}".format(x)

工程结构的演进

初级版本

如果只是想对某些内容做快速验证,那一个main文件即可

.
└── src/
    └── main.py

抽方法

如果想抽一些通用方法出来,那么结构会变成这样:

.
└── src/
    ├── main.py
    └── util.py

注意这里无法用相对引用,因为两个文件不在同一个Package中。要引用,直接import util即可。

跨项目复用Package

如果要抽取的东西足够多,那么就值得使用Package了。抽出Package来之后,可以实现其跨项目复用。

.
└── src/
    ├── main.py
    └── MyUtils/
        ├── __init__.py 
        ├── utils.py
        └── helpers.py

要注意的是,main.py,一定要在Package外

终极形态

呐,终于,我们的项目一步步成长为了个野兽...

.
└── src/
    ├── main.py
    ├── PackageA/
    │   ├── __init__.py
    │   ├── logic.py
    │   ├── SubPackageA1/
    │   │   ├── __init__.py
    │   │   └── util.py
    │   └── SubPackageA2/
    │       ├── __init__.py
    │       └── otherUtil.py
    └── PackageB/
        ├── __init__.py
        └── helpers.py

结尾

本篇,我们聊到了package,至此,这一大部分的文章结束了。接下来,我们会一起探索下并发编程相关知识点。

参考文献

【遇见Python】模块 & 包管理 一些冷门知识点(Part I) - 掘金 (juejin.cn)

【遇见Python】Define、Module & Package(Part II) - 掘金 (juejin.cn)

ImportError: attempted relative import with no known parent package (iq-inc.com)

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情