簡體   English   中英

顯示是否從字節碼加載 Python 模塊

[英]Show whether a Python module is loaded from bytecode

我正在嘗試調試Hy對字節碼的使用。 特別是,每次導入模塊時,我都想查看它實際導入的路徑,無論是源代碼還是字節碼。 在底層,Hy 使用importlib管理模塊。 它沒有明確地讀取或寫入字節碼; 這由importlib.machinery.SourceFileLoader 所以看起來我想要做的是猴子補丁 Python 的導入系統,以在每次導入發生時打印導入路徑。 我怎樣才能做到這一點? 一旦我了解了如何為 Python 做這件事,我應該能夠弄清楚如何為 Hy 做這件事。

不涉及編碼的最簡單方法是使用兩個(!)詳細標志啟動 Python:

python -vv myscript.py

您將獲得大量輸出,包括所有導入語句和 Python 嘗試訪問以加載模塊的所有文件。 在這個例子中,我有一個簡單的 python 腳本,它確實import json

lots of output!
[...]
# trying /tmp/json.cpython-310-x86_64-linux-gnu.so                                                                                                                                              
# trying /tmp/json.abi3.so                                                                                                                                                                      
# trying /tmp/json.so                                                                                                                                                                           
# trying /tmp/json.py                                                                                                                                                                           
# trying /tmp/json.pyc                                                                                                                                                                          
# /usr/lib/python3.10/json/__pycache__/__init__.cpython-310.pyc matches /usr/lib/python3.10/json/__init__.py                                                                                    
# code object from '/usr/lib/python3.10/json/__pycache__/__init__.cpython-310.pyc' 
[...]

或者但更復雜:您可以更改import語句本身。 為此,您可以覆蓋由import語句本身調用的__import__ 這樣您就可以打印出所有import實際打開的文件。

似乎一個不錯的選擇是將importlib.machinery.SourceFileLoader(fullname, path)importlib.machinery.SourcelessFileLoader(fullname, path)動態修補到每個打印或寫入變量(a)調用方法和(b)傳遞給函數的參數。

如果您需要做的只是:

我想查看它實際導入的路徑,無論是源代碼還是字節碼

而且你不需要導入來“正常工作”,也許你可以做這樣的修改版本。 例如,我快速修改了他們的示例代碼來得到這個,我沒有測試它,所以它可能不能完全工作,但它應該讓你走上正確的軌道:

# custom class to be the mock return value
class MockSourceLoader:

    # mock SourceFileLoader method always returns that the module was loaded from source and its path

    def SourceFileLoader(fullname, path):
        return {"load type": "source", "fullname": fullname, "path": path}

def check_how_imported(monkeypatch):

    # Any arguments may be passed and mock_get() will always return our
    # mocked object
    def mock_get(*args, **kwargs):
        return MockSourceLoader

    # apply the monkeypatch
    monkeypatch.setattr(importlib.machinery, SourceFileLoader, SourceFileLoader)

您當然會為SourcelessFileLoader的無源文件加載提供類似的模擬

以供參考:

暫無
暫無

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

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