包是一种经过".模块名"来组织python模块名称空间的方式。咱们建立的每一个文件夹均可以被称之为包。python2中规定,包内必须存在__init__.py文件。建立包的目的不是为了运行,而是被导入使用。包只是一种形式而已。python
import os os.makedirs('glance/api') os.makedirs('glance/cmd') os.makedirs('glance/db') l = [] l.append(open('glance/__init__.py', 'w')) l.append(open('glance/api/__init__.py', 'w')) l.append(open('glance/api/policy.py', 'w')) l.append(open('glance/api/versions.py', 'w')) l.append(open('glance/cmd/__init__.py', 'w')) l.append(open('glance/cmd/manage.py', 'w')) l.append(open('glance/db/__init__.py', 'w')) l.append(open('glance/db/models.py', 'w')) map(lambda f: f.close(), l)
获得以下目录结构:mysql
各文件中写有以下内容:sql
# policy.py def get(): print("from policy.py") # versions.py def create_resource(conf): print("from version.py: ", conf) # manage.py def main(): print("from manage.py") # models.py def register_models(engine): print("from models.py: ", engine)
# 与glance文件夹同目录下test.py import glance.db.models glance.db.models.register_models("mysql") 结果: from models.py: mysql
采用from xxx import xxx这种形式,import后面不能够出现"."。也就是说,from a.b import c是正确的,而from a import b.c是错误的api
# 与glance文件夹同目录下test.py from glance.db.models import register_models register_models("mysql") 结果: from models.py: mysql
不论使用哪一种方式导入一个包,只要是第一次导入包或者是包的任何其它部分。都会先执行__init__.py文件。app
# glance文件夹下的__init__.py文件 print("我是glance的__init__.py文件")
# 与glance文件夹同目录下test.py import glance 结果: 我是glance的__init__.py文件
绝对导入,是按sys.path路径寻找包,若是包不在sys.path列表中,可将包移至路径中。也可append包路径到sys.path中,但通常不这样作。spa
# policy.py from glance.api.versions import create_resource def get(): create_resource("mysql") print("from policy.py")
# 与glance文件夹同目录下的test.py from glance.api.policy import get get() 结果: 我是glance的__init__.py文件 from version.py: mysql from policy.py
在相对导入中,python不容许你运行的程序导包的时候超过当前包的范围。code
# policy.py from ..cmd import manage def get(): manage.main() print("from policy.py") get() 结果: ValueError: attempted relative import beyond top-level package
若是在包内使用了相对导入,那么在使用该包内信息的时候,只能在包外面导入blog
在包内导入则报错:内存
# policy.py from . import versions def get(): versions.create_resource("mysql") print("from policy.py") get() 结果: ImportError: cannot import name 'versions'
在包外导入,运行成功:get
# policy.py from . import versions def get(): versions.create_resource("mysql") print("from policy.py")
# 与glance文件夹同目录下的test.py from glance.api.policy import get get() 结果: 我是glance的__init__.py文件 from version.py: mysql from policy.py
单独导入一个包glance,,若是在包中__init__.py文件中并无关于子包的加载,此时导入的glance什么都作不了。
在__init__.py中加载子包可使用绝对路径加载,也可以使用相对路径加载
# glance文件夹下的__init__.py文件
from glance import api
# glance/api/__init__.py文件 from glance.api import policy
# glance/api/policy.py def get(): print("from policy.py")
# 与glance文件夹同目录下的test.py import glance glance.api.policy.get() 结果: from policy.py