簡體   English   中英

“導入”更喜歡 -.pyd (.so) 還是 .py?

[英]What does “import” prefer - .pyd (.so) or .py?

我在同一目錄中有 2 個文件,一個已編譯的庫文件和一個源文件:

.
├── a.py
└── a.pyd

看起來import a實際上導入了a.pyd模塊。 但我找不到一些官方文件來保證這一點。

有人知道不同文件類型的導入順序嗎?

同樣的問題適用於 Unix Python 擴展 (.so)

在典型的 Python 安裝中, ExtensionFileLoader class 優先於用於.py文件的SourceFileLoader 它是處理.pyd文件導入的ExtensionFileLoader ,在 Windows 機器上,您會發現在.pyd中注冊的importlib.machinery.EXTENSION_SUFFIXES (注意:在 Linux/macOS 上,它將有.so代替)。

因此,在同一目錄內發生名稱沖突的情況下(按順序查看sys.path時,這意味着“平局”), a.pyd文件優先於a.py文件。 您可以驗證在創建空a.pyda.py文件時,語句import a會嘗試加載 DLL(當然會失敗)。

要查看 CPython 源代碼中的優先級,請importlib._bootstrap_external. _get_supported_file_loaders importlib._bootstrap_external. _get_supported_file_loaders

def _get_supported_file_loaders():
    """Returns a list of file-based module loaders.
    Each item is a tuple (loader, suffixes).
    """
    extensions = ExtensionFileLoader, _imp.extension_suffixes()
    source = SourceFileLoader, SOURCE_SUFFIXES
    bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES
    return [extensions, source, bytecode]  # <-- extensions before source!

有關文檔參考,請參閱http://www.python.org/doc/essays/packages/

如果我有一個模塊和一個 Package 同名怎么辦?

您可能有一個目錄(在 sys.path 上),其中既有模塊 spam.py 又有一個子目錄 spam,其中包含_init _.py(沒有_init _.py,目錄不會被識別為包)。 在這種情況下,子目錄優先,導入垃圾郵件將忽略 spam.py 文件,而是加載 package 垃圾郵件。 如果您希望模塊 spam.py 具有優先權,則必須將其放在 sys.path 中較早的目錄中。

(提示:搜索順序由function imp.get_suffixes()返回的后綴列表決定。通常后綴的搜索順序如下:“.so”、“module.so”、“.py”、“ .pyc" 。目錄沒有顯式出現在此列表中,但位於其中的所有條目之前。)

該文檔沒有明確提及“.pyd”,但這是 Windows 等效於“.so”。 我剛剛在 Windows 機器上進行了測試,確實'.pyd'出現在后綴列表中的'.py'之前。

請注意,上面給出的參考資料已經很老了,自從寫了這篇文章以來,導入系統已經徹底改造:並且底層機制已經暴露給用戶訪問:你可以改變sys.meta_path來注冊你自己的加載器或改變優先級, 例如。 因此,現在可以自定義 '.py' 優先於 '.pyd',並且imp.get_suffixes()對任何事情說什么都沒關系(實際上,function 現在已棄用)。 當然,默認的 Python 安裝不會這樣做,默認優先級與上面提到的參考相同。

感謝wim的回答。

import importlib.util
print(importlib.util.find_spec('a'))

顯示結果

ModuleSpec(name='a', loader=<_frozen_importlib_external.ExtensionFileLoader object at 0x02A79EF0>, origin='a.pyd')

雖然我看不到 pyd,py 的順序。

至少我可以區分我將哪一個導入模塊化。

編輯:這回答了一個不同的問題,關於 .py vs.pyc 文件。 它不適用於此處要求的 .pyd 文件。

模塊導入邏輯在這里描述: https://docs.python.org/3/tutorial/modules.html#compiled-python-files

特別是,如果已編譯的.pyc 文件比 source.py 文件更新,則使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM