包是一種經過".模塊名"來組織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