Python包

时间:2020-02-23 14:43:07  来源:igfitidea点击:

今天,我们将学习Python包。
在继续本教程之前,您应该了解有关Python模块的知识,您可以在这里找到它。

Python包

Python软件包是目录中提供软件包层次结构的模块的集合。
更详细地说,python包是通过使用"点分模块名称"来构造python模块的一种方式。
因此,A.B实际上表明B是一个子模块,位于名为A的程序包下。

因此,由于模块是更好地处理函数和名称空间的方式,因此python包是在结构化方法中处理两个或者多个模块的方式。

假设您要设计用于处理音乐文件的模块集合。
看一下以下结构

music/                         Top-level package
    __init__.py               Initialize the music package
    formats/                 Subpackage for file format conversions
            __init__.py
            wavread.py
            wavwrite.py
            aiffread.py
            aiffwrite.py
            auread.py
            auwrite.py
            ...
    effects/                 Subpackage for sound effects
            __init__.py
            echo.py
            surround.py
            reverse.py
            ...
    filters/                 Subpackage for filters
            __init__.py
            equalizer.py
            vocoder.py
            karaoke.py
            ...

每个python软件包都需要有一个__init__.py文件,这将确保该目录被视为python软件包。
通常,init.py可以是一个空文件,也可以是该包的可执行初始化代码,或者可以设置__all__变量,这将在本教程的后面部分进行探讨。

要从包中导入单个模块,可以使用以下任何一种方法。

import music.formats.wavwrite

或者,

from music.formats import wavwrite

上面的命令加载子模块" music.formats.wavwrite"。
当然,必须使用全名进行引用。
假设模块" wavwrite.py"具有一个名为" writeFile(aFileName)"的函数,该函数以文件名作为参数。
因此,我们必须这样写:

import music.formats.wavwrite
...
...

music.formats.wavwrite.writeFile(outputFileName)

或者,第二种方式

from music.formats import wavwrite
...
...
wavwrite.writeFile(outputFileName)

还可能有人想知道,还有另一种变体可以直接导入所需的函数或者变量。

from music.formats.wavwrite import writeFile
...
...
writeFile(outputFileName)

我可以从Python包中导入*

一个好奇的读者可能想知道,如果像从模块导入时那样,从music.formats import *编写内容,那会是什么。
好吧,这可能会导致不良的副作用,并且还会消耗大量时间。

这样做的理想解决方案是,如果程序包作者提供了程序包的显式索引。
如果包的__init__.py代码定义了名为__all__的列表,则将其视为遇到来自" from.music.formats import *"的模块名称的索引。

让我们看一个不同的例子,以清楚地理解这个概念。
假设我们有一个这样的包结构:

其中您可以在\ music下看到一个__init__.py。
如果在下面定义了" all";

__all__ = ["admin", "apps", "models"]

然后,当遇到" from music import *"时,仅导入上面列表中列出的子模块。
其余子模块和变量将被忽略。

如果未定义__all__,则可以保证将其下的所有子模块都导入。
声明" from music import *"仅确保已导入音乐包。