URLhttps://learnscript.net/zh-hant/python-reference/import-system/module-finders/module-meta-path-finders/
    複製連結移至說明  範例

    Python 模組元路徑尋找器介紹

    閱讀 5:45·字數 1729·發佈 
    Youtube 頻道
    訂閱 375

    先決條件

    閱讀本節的先決條件是對 Python 模組尋找器有所掌握,你可以檢視Python 模組尋找器介紹一節來了解相關資訊。

    Python 模組元路徑尋找器

    Python 模組元路徑尋找器(Module Meta Path Finder)預設可以完成以下幾項工作,尋找內建模組,尋找凍結模組,尋找基於路徑的模組。

    事實上,元路徑尋找器是真正意義上的模組尋找器,在尋找定位模組的過程中,所有元路徑尋找器被依次調,當某個元路徑尋找器找到模組時,將傳回一個描述該模組的物件(整個尋找過程結束),否則,將傳回None。當所有元路徑尋找器均傳回None時,說明模組無法被定位,這將引發例外狀況ModuleNotFoundError

    檢視 Python 模組元路徑尋找器

    元路徑尋找器儲存在sys模組的meta_path變數中,你可以在互動模式中,輸入import syssys.meta_path兩行程式碼,來檢視目前的元路徑尋找器。如果是py檔案,則可以改寫sys.meta_pathprint(sys.meta_path)

    import sys
    sys.meta_path
    [<_distutils_hack.DistutilsMetaFinder object at >, <class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>]
    print_meta_path.py
    # 顯示元路徑尋找器
    import sys
    print(sys.meta_path)

    尋找 Python 內建和凍結模組

    元路徑尋找器 BuiltinImporter 和 FrozenImporter,分別用於尋找內建和凍結模組。當然,在 Python 啟動時,一些內建或凍結模組會自動匯入,並儲存在sys.modules中,他們再次被 BuiltinImporter 或 FrozenImporter 匯入的可能性不大,除非對應的快取被清除。

    廣義上的「內建模組」可以是凍結模組

    如果你將 Python 啟動後sys.modules中包含的模組稱為「內建模組」,那麽「內建模組」可以是凍結模組,基於路徑載入的模組,或真正意義上的內建(built-in)模組。比如,廣義上的「內建模組」os是一個凍結模組,廣義上的「內建模組」sys是一個真正的內建(built-in)模組。

    請註意,以上這些情況可能因為 Python 版本的不同而有所變化。

    模組

    要了解模組快取,你可以檢視Python 模組快取一段。

    在互動模式中,我們匯入模組os,使用globals()函式檢視全域資訊,發現匯入的模組os是一個凍結模組。刪除凍結模組尋找器 FrozenImporter 以及模組ossys.modules中的快取,再次執行import osglobals(),發現模組os不再是凍結模組。這是因為 FrozenImporter 尋找器被刪除,os是通過其他尋找器被定位的。

    import os
    globals()
    {'os': <module 'os' (frozen)>}
    import sys
    sys.meta_path
    [<_distutils_hack.DistutilsMetaFinder object at >, <class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>]
    del sys.meta_path[2]
    del sys.modules['os']
    import os
    globals()
    {'os': <module 'os' from ''>,}

    為何有些模組元路徑尋找器的類別名稱包含英文單字 Importer?

    BuiltinImporter 和 FrozenImporter 的準確翻譯,應該是內建匯入器和凍結匯入器,但由於匯入器同時具有尋找器和載入器的功能,因此,也可以稱他們為尋找器。

    尋找基於路徑的 Python 模組

    元路徑尋找器 PathFinder,也被稱為基於路徑尋找器,用於尋找基於模組搜尋路徑的模組,這大概是最為常見的情況,當你希望匯入第三方或自己編寫的模組或套件時, PathFinder 將開始工作。

    廣義上的「內建模組」可以是基於路徑載入的模組

    通過查詢sys.modules可以發現,在「內建模組」中,有不少是通過基於路徑尋找器來定位的。

    實作基於路徑尋找器的可拓展性

    模組尋找器的另一分類,路徑項目尋找器,是基於路徑尋找器的具體實作,因此,可以通過編寫路徑項目尋找器,拓展基於路徑尋找器的功能。比如,定位在網路上儲存的腳本。

    模組搜尋路徑

    要了解模組搜尋路徑,你可以檢視Python 模組搜尋路徑介紹,模組搜尋路徑中的目錄有哪些一節。

    Python 模組元路徑尋找器的優先順序

    如前所述,在尋找模組時,元路徑尋找器是被依次呼叫的,如果他們在sys.meta_path中的順序被改變,那麽可能會引發意想不到的問題。

    下面,我們編寫了一個自己的os模組,將命令列切換至該模組所在的目錄,然後進入 Python 互動模式,把優先順序較低的 PathFinder 尋找器放到串列sys.meta_path的首位,清除os模組的快取並重新匯入,優先順序最高的 PathFinder 將找到我們編寫的os模組。

    os.py
    print('我不是那個 os 模組!')
    import sys
    sys.meta_path
    [<_distutils_hack.DistutilsMetaFinder object at >, <class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>]
    sys.meta_path.reverse()
    del sys.modules['os']
    import os
    我不是那個 os 模組!

    原始碼

    print_meta_path.py·codebeatme/python-reference·GitHub
    os.py·codebeatme/python-reference·GitHub