當你的模塊文件愈來愈多,就須要對模塊文件進行劃分,好比把負責跟數據庫交互的都放一個文件夾,把與頁面交互相互的放入一個文件夾。python
像上面這樣,一個文件夾管理多個模塊文件,這個文件夾就被稱爲包。數據庫
那不一樣包之間的模塊如何相互導入呢?app
crm/views.py 內容函數
def sayhi(): print('hello world!')
經過 manage.py 調用spa
from my_pro.crm import views #從包裏導入包裏的文件 views.sayhi()
在文件夾下,加一個 __inint__.py 這個文件就會被 python2 識別爲一個包,python3 不加也能被識別爲包。3d
從 manage.py 裏導入 views.py,從 views.py 裏導入 settings.py。由於在 sys.path 裏已經把 manage.py 所在的位置看成入口導入,即 sys.path 裏的 " " ,因此 views.py 能夠從高它一級的 proj 裏導入 settings.py 。code
從 views.py 裏直接導入 settings.py ,而 settings.py 存在於高 views.py 一級的 proj 裏,因爲入口文件是 views.py ,因此 settings.py 不存在於 sys.path 裏面,須要獲取settings 的絕對路徑添加到 sys.path 裏,進行模塊導入。orm
import sys, os #獲取此程序所在文件的絕對目錄的上一層的上一層,即proj所在絕對路徑 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #將proj所在文件路徑添加到sys.path裏面,即導入模塊的搜尋範圍 sys.path.append(BASE_DIR) from proj import settings
相對導入blog
從當前目錄下直接導入,意思是被導入的文件和導入文件兩者爲同級別文件,存在於同一個文件夾下。it
#在 views.py 裏導入 models.py from . import models
在 views.py 裏導入 settings.py
# '.' 表明當前目錄,那 '..proj' 應該就能表明當前目錄的平級中的 proj 文件 from ..proj import settings
執行結果報錯了
SystemError: Parent module '' not loaded, cannot perform relative import
或者有人會看到這個錯
ValueError: attempted relative import beyond top-level package
其實這兩個錯誤的緣由歸根結底是同樣的:在涉及到相對導入時,package 所對應的文件夾必須正確的被 python 解釋器視做 package ,而不是普通文件夾。不然因爲不被視做 package ,沒法利用 package 之間的嵌套關係實現 python 中包的相對導入。
文件夾被視 python 解釋器視做 package 須要知足兩個條件:
因此這個問題的解決辦法就是,既然你在 views.py 裏執行了相對導入,那就不要把 view.py 看成入口程序,能夠經過上一級的 manage.py 調用 views.py 。
正確的代碼目錄結構以下:
再執行 manage.py 就不會報錯了。
注:雖然 python 支持相對導入,但對模塊間的路徑關係要求比較嚴格,處理不當就容易出錯,so並不建議在項目裏常常使用。