10.3 Python中的包
如果模块名重复,使用包(Package) 这个概念,是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录下。简单的理解就是“文件夹”,只不过必须存在一个名为__init__.py
的文件。
10.3.1 Python程序的包结构
如下图所示:
10.3.2 创建和使用包
- 创建包
必须创建一个名为__Init__.py
文件,里边可以没有内容。在某一个文件夹创建一个文件夹,里边有一个名为__Init__.py
文件就可以了。例如,在该练习python中的文件夹下,连理一个名为settings
的文件夹,里边建立一个名为__init__,py
的文件。
- 使用包
创建包以后,就可以在包中创建相应的模块,然后再使用import语句从包中加载模块。例如,在settings
包中新建一个名为size.py
的文件:
width = 800
height = 1000
则在调用的时候:
import settings.size
if __name__ == '__main__':
print('宽度是:', settings.size.width)
print('高度是:', settings.size.height)
'''
宽度是: 800
高度是: 1000
'''
以下几种写法也是正确的:
from settings import size
if __name__ == '__main__':
print('宽度是:', size.width)
print('高度是:', size.height)
'''
宽度是: 800
高度是: 1000
'''
或者是:
from settings.size import width, height
if __name__ == '__main__':
print('宽度是:', width)
print('高度是:', height)
'''
宽度是: 800
高度是: 1000
'''
当然,可以使用星号“*”代替定义名,表示加载该模块下的全部定义。
在指定包中创建通用的设置和获取尺寸的模块,修改size.py
文件:
_width = 800
_height = 1000
def change(w, h):
global _width # 全局变量
_width = w # 重新赋值
global _height # 全局变量
_height = h # 重新赋值
def getWidth():
global _width
return _width
def getHeight():
global _height
return _height
在settings包的上一层目录中创建一个名称为main.py的文件:
from settings.size import *
if __name__ == '__main__':
change(1024, 768)
print('宽度是:', getHeight())
print('高度是:', getWidth())
'''
宽度是: 768
高度是: 1024
'''
10.3.3 以主程序的形式执行
创建一个名称为christmastree
的模块,内容如下:
pinetree = '我是一个松树' #定义全局变量
def fun_christmastree(): # 定义函数
pinetree = '挂上彩灯、礼物。。。我是一棵圣诞树' # 定义局部变量
print(pinetree)
print('\n下雪了。。。。。\n')
print('=======开始做梦。。。=========')
fun_christmastree()
print('=======梦醒了=================')
pinetree = '我身上落满了雪花,' + pinetree + '-_-'
print('全局变量值为:', pinetree)
'''
下雪了。。。。。
=======开始做梦。。。=========
挂上彩灯、礼物。。。我是一棵圣诞树
=======梦醒了=================
全局变量值为: 我身上落满了雪花,我是一个松树-_-
我身上落满了雪花,我是一个松树-_-
'''
在与christmastree
模块同级的目录下创建一个名称为main.py
的文件,代码如下:
import christmastree
print(christmastree.pinetree)
'''
下雪了。。。。。
=======开始做梦。。。=========
挂上彩灯、礼物。。。我是一棵圣诞树
=======梦醒了=================
全局变量值为: 我身上落满了雪花,我是一个松树-_-
我身上落满了雪花,我是一个松树-_-
'''
从上述输出结果可以看出,在导入christmastree.py
模块后,不仅输出了我们需要的全局变量,也顺带的执行了该模块中的其余代码的输出,显然这不是我们想要看到的结果。实际上,可以在模块中将原本直接执行的测试代码放在一个if
语句中:
pinetree = '我是一个松树' #定义全局变量
def fun_christmastree(): # 定义函数
pinetree = '挂上彩灯、礼物。。。我是一棵圣诞树' # 定义局部变量
print(pinetree)
if __name__ == '__main__':
print('\n下雪了。。。。。\n')
print('=======开始做梦。。。=========')
fun_christmastree()
print('=======梦醒了=================')
pinetree = '我身上落满了雪花,' + pinetree + '-_-'
print('全局变量值为:', pinetree)
再次执行mian.py
文件,结果如下面所示:
'''
我是一个松树
'''
在每个模块的定义中都包括一个记录模块名称的变量__name__
,程序可以检查该变量,以确定它们在哪个模块中执行。如果一个模块不是被导入其他程序中执行,那么它可能在解释器的顶级模块中执行。顶级模块的__name__
变量的值为__main__
。