1. 程式人生 > 其它 >python動態載入pyd,so

python動態載入pyd,so

技術標籤:pythonpython

最近做python專案用到了動態載入模組這個技術,需求很明瞭。

0、適用於熱執行,在特定的場景呼叫(比如安裝包裡面提供了install.so,用於安裝安裝包本身)

1、不干擾已經存在的模組,就算名字相同

2、開袋即食,用完回收,不長久持有引用

3、需要相容.pyd(windows)、.so(linux)

4、使用完整的絕對路徑,不依賴sys.path

5、需要相容3.5+,目前我用的是python3.8

百度就不用說了,一大堆import的初級用法,沒有相關的文獻可以參考,改變陣地去Google搜尋了一番,發現.py的載入和.pyd的載入大有不同,具體看文章(第12個回答) ->

堆疊論壇

具體的不同之處就是

ExtensionFileLoader 用於載入擴充套件檔案,也就是我們編譯後的.so或者.pyd
SourcelessFileLoader 用於載入原始檔,就是我們經常看見的.py原始檔

然後,廢話不多說,給一個開袋即食(相對,版本還是要匹配的)的函式:

@staticmethod
def path_import(file):
    """
        匯入模組
    :param file:
    :return:
    """
    print("\n******************* 開始動態載入模組 *************************")
    loader_details = (
        importlib.machinery.ExtensionFileLoader,
        importlib.machinery.EXTENSION_SUFFIXES
    )
    tools_finder = importlib.machinery.FileFinder(os.path.dirname(file), loader_details)
    print("FileFinder: ", tools_finder)
    toolbox_specs = tools_finder.find_spec(os.path.basename(file).split(".")[0])
    print("find_spec: ", toolbox_specs)
    toolbox = importlib.util.module_from_spec(toolbox_specs)
    print("module: ", toolbox)
    toolbox_specs.loader.exec_module(toolbox)
    print("匯入成功 path_import(): ", toolbox)
    print("檢查sys中是否包含了此模組: ", toolbox in sys.modules)
    print("******************* 動態載入模組完成 *************************\n")
    return toolbox

需要匯入的庫:

import os
import importlib.machinery
import importlib.util

上面書寫的函式經過驗證是可用的,當然,我的版本是py3.8,各位朋友要看清楚自己的版本,版本不適用的話要去堆疊那裡看看自己的需求的對應實現(有較低版本的相容程式碼)。

無圖無真相,給大家貼一動態載入.so成功的截圖:

需求記錄完成,希望可以幫到大家。