简述
通常情况下,在使用电脑的过程中,我们不会把所有的文件都存储在同一个位置,因为这样不便于管理和访问。因此,使用一个组织良好的目录层次结构很有必要。
所谓组织良好,就是将类似的文件保存在同一个目录中。例如,将所有歌曲保存在“音乐”目录中,将所有电影、电视保存在“视频”目录中。。。与此类似,Python 中提供了包和模块的概念,包用于目录,模块用于文件(.py)。
| 版权声明:一去、二三里,未经博主允许不得转载。
包的管理
在开发项目的过程中,随着应用程序的规模越来越大,会有很多模块。这时,需要将类似的模块放在一个包中,并且不同的模块放在不同的包中,这不仅使项目更易于管理,而且在概念上更加清晰。
一个目录可以包含子目录和文件,类似地,一个 Python 包也可以有子包和模块。
为了能让 Python 将目录视为一个包,该目录必须包含一个名为 __init__.py
的文件。该文件可以是空的,也可以包含有效的 Python 代码,这些代码将会在包被导入的时候执行,所以它可以用来初始化一个包,例如:确保其他模块被导入或设置一些值。
来创建一个 Sound
包,其中包含两个模块 play.py
和 pause.py
,目录结构如下:
[wang@localhost Game]$ tree Sound
Sound
├── __init__.py
├── pause.py
└── play.py0 directories, 3 files
模块 play.py
的内容为:
def func():print('play...')
模块 pause.py
的内容为:
def func():print('pause...')
__init__.py
文件暂时为空,下面有专门介绍。
包的访问
假设,目录 Sound
位于调用 shell 的目录中,或者包含在搜索路径或环境变量 PYTHONPATH
中。
当从交互式的 Python shell 中导入 Sound
时,看看会发生了什么?
>>> import Sound
>>>
>>> Sound
<module 'Sound' from '/home/wang/workspace/Game/Sound/__init__.py'>
>>>
>>> Sound/play
...
NameError: name 'play' is not defined
>>>
>>> Sound/pause
...
NameError: name 'pause' is not defined
可以看到包 Sound
已经被加载了,但是模块 play
和 pause
并没有。
所以,不能仅通过导入 Sound
来访问它们,可以使用下述导入方式:
>>> from Sound import play, pause
>>>
>>> play.func()
play...
>>>
>>> pause.func()
pause...
__init__.py
文件
目前为止,__init__.py
依然为空,那么这个文件究竟是干什么的?
为该文件添加一行简单的代码:
print('Sound is imported...')
导入 Sound
,看看会发生什么?
>>> import Sound
Sound is imported...
没错,__init__.py
中的代码被执行了。也就是说,在包导入的时候,会自动执行其包含的 __init__.py
的所有代码。
这样以来,上面的问题又多了一种解决方案,可以使用 __init__.py
自动加载这些模块,将下面的代码添加到该文件中进行初始化:
import Sound.play
import Sound.pause
再次访问 play
和 pause
:
>>> import Sound
>>>
>>> Sound.play.func()
play...
>>>
>>> Sound.pause.func()
pause...
OK,完美运行!