繁体   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