包是一种通过使用“模块名”来组织python模块的名称空间的方式。
无论是import形式还是from...import形式,凡是在导入语句中(不是在使用时)遇到带点的,就需要意识到——这是包。
包是目录级的,文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)。
import导入文件时,产生名称空间中的名字来源于文件,import包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件。
在python3中,即使包下没有__init__.py文件,import包仍然不会报错,而在python2中,包下一定要有该文件,否则import包报错。
[root@7 module]# tree.├── bonf #包│?? ├── __pycache__│?? │?? └── test1.cpython-36.pyc #导入的时候生成的缓存文件│?? └── test1.py 模块└── conf #包 ├── __pycache__ │?? ├── test2.cpython-36.pyc │?? └── test1.cpython-36.pyc ├── test2.py #模块 └── test.py #模块4 directories, 6 files#包中的内容#!/usr/bin/env pythondef func1(): #bonf包下模块test1中有个func1函数 print("bonf") ~ "bonf/test1.py" 3L, 50C #另一个包conf#!/usr/bin/env pythondef func1(): #包conf下模块test1下函数func1 print("函数1") ~ "conf/test1.py" 3L, 53C
现在来导入这两个包
>>> import bonf.test1>>> import conf.test1 #没有报错
现在来引用其中的函数
>>> bonf.test1.func1()bonf>>> conf.test1.func1() #没有毛病函数1
我们可以看到,两个包下有同名的模块也不会冲突,它们来自各自的命名空间。
也是可以使用from-import,但是这样会覆盖命名空间。
>>> from conf import test1>>> test1.func1()函数1>>> from bonf import test1>>> test1.func1()bonf
多层也是可以的
>>> import bonf.donf.test10>>> donf.test10.func() #少一层都不行,路径要对Traceback (most recent call last): File "", line 1, in NameError: name 'donf' is not defined>>> bonf.donf.test10.func()2层
相对导入和绝对导入
>>> from bonf import test1 #绝对>>> from . import test1 #相对