【问题标题】:Determining path of the translated cython pyx source file确定翻译后的 cython pyx 源文件的路径
【发布时间】:2020-09-18 14:14:33
【问题描述】:

我有一个 cython 源文件,我想在其中导入本地 python 模块。 这个 cython 源文件使用 cython(python3 语法)翻译成 c++ 源,然后编译成库,然后在 C++ 主程序中使用。

在执行主程序时,本地 python 模块的导入失败,因为执行的代码不知道其模块的位置。我尝试在我的 pyx 文件中使用 python3 的本地导入功能,但无济于事。

我想出的唯一可行的解​​决方案(也是最明显的一个)是使用sys.path.append 更新python 的模块搜索路径。问题是我必须对这条路径进行硬编码,这很难看。

如果可以在源文件的 cython 代码位置中检索(我可以从中导出绝对路径),我试图找到任何提示,但没有成功。通常的 Pythonic 方法会失败 - 例如,原因之一是 __file__ 的计算结果为 built-in,并且在运行时检索绝对路径会给出运行可执行文件的路径。

旁注:我所做的搜索之一是在 GitHub 搜索引擎中查询 cython 文件中出现的 sys.path.append。有趣的是,所有结果要么具有硬编码的路径,要么与文件系统中 cython 源文件的位置无关。

所以我的问题是,是否可以在 cython 代码中可靠地检索其源文件的位置?

免责声明:我可以想象在构建从 cython 派生的 C++ 文件时检测构建系统以将预处理器变量集传递给相关路径,然后在代码中访问它,但这看起来有点矫枉过正。


示例:

bulba.py

def fn():
    print('blah')

bulbulator.pyx

# tag: cpp
# tag: py3only

import sys
sys.path.append('/absolute_path_to_folder_with_bulba_py') # <-- this is the key part. I'd like to replace the hardcoded path with something better

from bulba import fn
fn()

bulbulator.pyx 被翻译成 cpp:

cython -3 --cplus bulbulator.pyx

lib_wrapper.cpp (这个库和链接到它的可执行文件的位置与 py/pyx 源代码及其翻译的 c++ 部分的位置不同)

// import headers generated by cython
#include "bulbulator_api.h"
#include "bulbulator.h"

// global initialization of the cythonized part
__attribute__((constructor))
static void
__library_init()
{
    if (int err = PyImport_AppendInittab("bulbulator", PyInit_bulbulator); err != 0)
    {
        std::fprintf(stderr, "PyImport_AppendInittab(bulbulator) failed with status code=%d\n", err);
        std::exit(1);
    }

    Py_Initialize();

    if (import_bulbulator() == -1) // <-- here it fails if I comment out sys.path.append, because bulbulator needs to know the location of bulba.py
    {
        PyErr_Print();
    }
}

【问题讨论】:

  • @ead pyx 文件被翻译成cpp,然后被编译成一个静态库,一个可执行文件与之链接。我有另一个应用程序,它遵循完全相同的方案,只是它没有在 cythonized 代码中导入本地 python 模块并且它可以工作。
  • @ead 我不确定您提供的链接中的解决方案是否可以在这里工作。看起来它适用于导入模块也是 pyx 模块的情况,而在我的情况下它是 vanilla python,所以没有定义函数可以传递给PyImport_AppendInittab

标签: cython


【解决方案1】:

我宁愿将bulba.py 放在exe 旁边,但也可以返回到Cython 扩展的绝对路径,例如使用编译时环境变量(有关更多详细信息,请参阅cython --help) ,我们就叫它ADDITIONAL_SYS_PATH

import sys
sys.path.append(ADDITIONAL_SYS_PATH) 

from bulba import fn
fn()

现在通过以下方式运行 Cython:

cython -3 --cplus -E ADDITIONAL_SYS_PATH="the path to dir"

将正确的值设置为ADDITIONAL_SYS_PATH


Cython 将 pyx 文件的名称保存在生成​​的 cpp 中(例如用于运行时错误报告),但此名称不包含完整路径,因此我们需要手动提供路径。

【讨论】:

    猜你喜欢
    • 2018-11-10
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    • 2023-02-20
    相关资源
    最近更新 更多