gpt4 book ai didi

module - 如何重新加载 Python3 C 扩展模块?

转载 作者:行者123 更新时间:2023-12-03 14:39:44 25 4
gpt4 key购买 nike

我为 Python 3.2 编写了一个 C 扩展 (mycext.c)。该扩展依赖于存储在 C 头文件 (myconst.h) 中的常量数据。头文件由 Python 脚本生成。在同一个脚本中,我使用了最近编译的模块。 Python3 myscript(未完整显示)中的工作流程如下:

configure_C_header_constants() 
write_constants_to_C_header() # write myconst.h
os.system('python3 setup.py install --user') # compile mycext
import mycext
mycext.do_stuff()

这是第一次在 Python session 中完美运行。如果我在同一 session 中重复该过程(例如,在单元测试的两个不同测试用例中),则始终(重新)加载 mycext 的第一个编译版本。

如何有效地重新加载具有最新编译版本的扩展模块?

最佳答案

您可以使用 imp.reload() 在 Python 3.x 中重新加载模块功能。 (这个函数曾经是 Python 2.x 的内置函数。一定要阅读文档——有一些警告!)

Python的导入机制永远不会dlclose()一个共享库。加载后,库将一直保留到进程终止。

您的选择(按有用性递减排序):

  • 将模块导入移动到子进程,重新编译后再次调用子进程,即你有一个Python脚本do_stuff.py就是这样
    import mycext
    mycext.do_stuff()

    你调用这个脚本使用
    subprocess.call([sys.executable, "do_stuff.py"])
  • 将头文件中的编译时常量转换为可以从 Python 更改的变量,从而无需重新加载模块。
  • 手动 dlclose()删除对模块的所有引用后的库(有点脆弱,因为您自己没有持有所有引用)。
  • 滚动您自己的导入机制。

    这是一个如何做到这一点的示例。我写了一个最小的 Python C 扩展 mini.so , 只导出一个名为 version 的整数.
    >>> import ctypes
    >>> libdl = ctypes.CDLL("libdl.so")
    >>> libdl.dlclose.argtypes = [ctypes.c_void_p]
    >>> so = ctypes.PyDLL("./mini.so")
    >>> so.PyInit_mini.argtypes = []
    >>> so.PyInit_mini.restype = ctypes.py_object
    >>> mini = so.PyInit_mini()
    >>> mini.version
    1
    >>> del mini
    >>> libdl.dlclose(so._handle)
    0
    >>> del so

    此时,我增加了 mini.c 中的版本号并重新编译。
    >>> so = ctypes.PyDLL("./mini.so")
    >>> so.PyInit_mini.argtypes = []
    >>> so.PyInit_mini.restype = ctypes.py_object
    >>> mini = so.PyInit_mini()
    >>> mini.version
    2

    可以看到使用的是新版本的模块。

    供引用和实验,这里是mini.c :
    #include <Python.h>

    static struct PyModuleDef minimodule = {
    PyModuleDef_HEAD_INIT, "mini", NULL, -1, NULL
    };

    PyMODINIT_FUNC
    PyInit_mini()
    {
    PyObject *m = PyModule_Create(&minimodule);
    PyModule_AddObject(m, "version", PyLong_FromLong(1));
    return m;
    }
  • 关于module - 如何重新加载 Python3 C 扩展模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8295555/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com