Python基礎(十八)
阿新 • • 發佈:2019-10-07
今日主要內容
- 包
一、包
(一)什麼是包
- 只要是含有
__init__.py
檔案的資料夾就是一個包 - 包的本質其實就是一個資料夾,利用包將不同功能的模組組織起來,以此來提高程式的結構性和可維護性
- 包是用來匯入的,不是用來執行的,所以它和軟體開發規範分檔案管理還是有區別的,一個是專案,一個是用來匯入的包
- 正因為包是用來匯入的,所以執行檔案一定要放在包的外面
(二)建立一個包
利用程式碼建立一個包
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/test.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/models.py','w')) map(lambda f:f.close() ,l)
- 下述所有內容,均以此圖結構為基礎
(三)__init__.py
檔案
在我們匯入包的時候,其實本質上匯入的就是
__init__.py
檔案,直譯器會自動執行__init__.py
檔案中的內容# glance/__init__.py print("這裡是glance下的__init__.py檔案") # run.py import glance 執行結果: 這裡是glance下的__init__.py檔案
(四)包的匯入
- 包的匯入,須注意兩點內容:
- 匯入時無論是使用
import
還是使用from xxx import xxx
匯入,點的前面必須是一個包 - 使用
from xxx import xxx
- 匯入時無論是使用
常規匯入
- import匯入
# policy.py def policy_func(): print("這是policy檔案中的函式") # run.py import glance.api.policy glance.api.policy.policy_func() 執行結果: 這是policy檔案中的函式 # 成功匯入
- from import匯入
# policy.py def policy_func(): print("這是policy檔案中的函式") # run.py from glance.api.policy import policy_func policy_func() 執行結果: 這是policy檔案中的函式 # 成功匯入
包內部之間的匯入:
包內部之間的相互引用,只能用絕對匯入和相對匯入,不能直接匯入,比如
policy.py
檔案需要匯入versions.py
檔案中的函式,如果直接import匯入會報找不到該模組的錯誤- 包內部互相引用的時候不能直接匯入
# versions.py def versions_func(): print("這是versions檔案中的函式") # policy.py import versions # 直接匯入versions模組,在外面的run檔案中執行,就無法找到versions模組 def policy_func(): versions.versions_func() print("這是policy檔案中的函式") # run.py from glance.api import policy policy.policy_func() 執行結果: ModuleNotFoundError: No module named 'versions'
- 原因分析:如果直接在policy檔案中執行程式,完全沒有問題,因為此時policy檔案的模組查詢路徑中包含versions模組,但是**包是用來匯入的,如果在包外的run檔案中匯入policy模組,此時模組查詢路徑就變為了run檔案所在的路徑,所以當policy檔案匯入versions模組時,路徑下並沒有versions模組,所以找不到該模組
絕對匯入:
# versions.py def versions_func(): print("這是versions檔案中的函式") # policy.py from glance.api import versions def policy_func(): versions.versions_func() print("這是policy檔案中的函式") # run.py from glance.api import policy policy.policy_func() 執行結果: 這是versions檔案中的函式 這是policy檔案中的函式
- 相對匯入:
# versions.py def versions_func(): print("這是versions檔案中的函式") # policy.py from . import versions def policy_func(): versions.versions_func() print("這是policy檔案中的函式") # run.py from glance.api import policy policy.policy_func() 執行結果: 這是versions檔案中的函式 這是policy檔案中的函式
- 只要使用了相對匯入的模組,只能作為模組使用,不能作為指令碼(終端中直接執行的檔案成為指令碼)使用,說白了就是不能直接執行
# versions.py def versions_func(): print("這是versions檔案中的函式") # policy.py from . import versions def policy_func(): versions.versions_func() print("這是policy檔案中的函式") 執行結果: ImportError: cannot import name 'versions'
單獨匯入包,並使用包內的包或模組
- 單獨匯入一個包,其本質上匯入的只是
__init__.py
檔案,包中其他的檔案並沒有被匯入
# policy.py def policy_func(): print("這是policy檔案中的函式") # run.py import glance # 只匯入了__init__.py檔案 glance.api.policy.policy_func() # 並不能使用 執行結果: AttributeError: module 'glance' has no attribute 'policy'
- 此時就要利用到
__init__.py
檔案了,__init__.py
檔案在包中起到了交接管理的作用,可以在__init__.py
檔案中匯入每個子檔案,也可以控制其是否能被匯入,所以每一個包中必須要有__init__.py
檔案
# policy.py def policy_func(): print("這是policy檔案中的函式") # glance/__init__.py from . import api # glance/api/__init__.py from . import policy # run.py import glance glance.api.policy.policy_func() 執行結果: 這是policy檔案中的函式
- 直接呼叫模組中的方法
# policy.py def policy_func(): print("這是policy檔案中的函式") # glance/__init__.py from .api import * # glance/api/__init__.py from .policy import * # run.py import glance glance.policy_func() 執行結果: 這是policy檔案中的函式
還可以通過
__all__
來控制模組和模組中函式的匯入- 控制模組匯入
# glance/__init__.py from .api import * # glance/api/__init__.py __all__ = ["versions"] # 只能匯入versions,其餘api下模組都不能被匯入 # run.py import glance glance.policy 執行結果: AttributeError: module 'glance' has no attribute 'policy'
- 控制方法匯入
# policy.py def policy_func(): print("這是policy檔案中的func") def policy_foo(): print("這是policy檔案中的foo") # glance/__init__.py from .api import * # glance/api/__init__.py from .policy import * __all__ = ["policy_foo"] # 控制只能匯入foo函式,其餘函式都不能被匯入 # run.py import glance glance.policy_func() 執行結果: AttributeError: module 'glance' has no attribute 'policy_func'
- 單獨匯入一個包,其本質上匯入的只是