C中的嵌入式python:有没有办法从zipped python存档中正确导入numpy?

时间:2017-05-07 19:05:18

标签: c python-2.7 numpy

似乎我无法在嵌入python的C应用程序中正确导入numpy,当使用包含所有python文件和二进制文件的本地.zip python文件时,而不是标准的python安装。这是我得到的错误:

  

zipimport:zlib可用
  python27.zip \ lib \ site-packages \ numpy_globals.pyc有糟糕的mtime
  zipimport:zlib可用
  import numpy._globals#从Zip中加载python27.zip \ Lib \ site-packages \ numpy_globals.py
  zipimport:zlib可用
  python27.zip \ lib \ site-packages \ numpy__config __。pyc有糟糕的mtime
  zipimport:zlib可用
  import numpy。 config #从Zip中加载python27.zip \ lib \ site-packages \ numpy__config __。py
  zipimport:zlib可用
  python27.zip \ lib \ site-packages \ numpy \ version.pyc有糟糕的mtime
  zipimport:zlib可用
  import numpy.version#从Zip中加载python27.zip \ lib \ site-packages \ numpy \ version.py
  zipimport:zlib可用
  python27.zip \ lib \ site-packages \ numpy_import_tools.pyc有错误的mtime
  zipimport:zlib可用   import numpy._import_tools#从Zip中加载python27.zip \ Lib \ site-packages \ numpy_import_tools.py
  zipimport:zlib可用
  python27.zip \ lib \ site-packages \ numpy \ add_newdocs.pyc有错误的mtime
  zipimport:zlib可用
  zipimport:zlib可用
  import math#builtin
  zipimport:zlib可用
  从zip python27.zip \ Lib \ site-packages \ numpy \ lib \ info.pyc加载导入numpy.lib.info#   zipimport:zlib可用
  zipimport:zlib可用
  zipimport:zlib可用
  python27.zip \ lib \ site-packages \ numpy \ core \ info.pyc有糟糕的mtime
  zipimport:zlib可用
  导入numpy.core.info#从Zip中加载python27.zip \ Lib \ site-packages \ numpy \ core \ info.py
  import numpy.core#从Zip中加载python27.zip \ Lib \ site-packages \ numpy \ core__init __。pyc
  从zip python27.zip \ Lib \ site-packages \ numpy \ lib \ type_check.pyc加载导入numpy.lib.type_check#   import numpy.lib#从Zip中加载python27.zip \ Lib \ site-packages \ numpy \ lib__init __。pyc
  import numpy.add_newdocs#从Zip中加载python27.zip \ Lib \ site-packages \ numpy \ add_newdocs.py
  import numpy#从Zip中加载python27.zip \ Lib \ site-packages \ numpy__init __。py
   无法导入名称多列

但是当我提取上述.zip文件,并运行python.exe解释器并导入numpy时,一切正常。

我从源代码x86 Release构建了python 2.7.13。之后从here安装了 numpy-1.11.3 + mkl-cp27-cp27m-win32.whl 文件,然后创建了一个python .zip存档,其中包含所有必需文件,遵循常见的文件夹结构。 / p>

这就是我的C代码的样子:

int main(int argc, char **argv)
{
    Py_VerboseFlag++;
    Py_NoSiteFlag++;

    Py_SetProgramName(argv[0]);
    Py_SetPythonHome(".");

    Py_Initialize();

    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path = ['.','python27.zip','python27.zip/DLLs','python27.zip/Lib', 'python27.zip/Lib/site-packages']");;
    PyRun_SimpleString("print sys.path");

    printf("\n");

    char filename[_MAX_PATH];
    _fullpath(filename, "mod1.py", _MAX_PATH);

    PyObject* main_module = PyImport_AddModule("__main__");
    PyObject* main_dict = PyModule_GetDict(main_module);
    PyObject *pyFileObj = PyFile_FromString(filename, "r");

    if (pyFileObj == NULL) {
        return -1;
    }

    FILE *pFile = PyFile_AsFile(pyFileObj);

    if (pFile == NULL)
        return -1;

    PyObject *result = PyRun_File(pFile, filename, Py_file_input, main_dict, main_dict);

    if (!result)
        print_error();

    printf("\n\n");


    Py_Finalize();
    getchar();

    return 0;
}

模块mod1.py,我正在执行包含这个:

import time
import json
import numpy

if __name__ == "__main__":
    print 'Success'

我知道这个错误来自于python无法加载 multiarray.pyd 这个共享库的事实。我需要在导入时单独处理这个场景吗? /> 是否可以从C应用程序的压缩,非标准python安装中正确导入numpy?

编辑:忘了提及以下内容:
  - 我的操作系统 Windows 10 x64版本1511(操作系统版本10586.545)
  - 当我在我的C ++二进制文件所在的Release文件夹中提取.zip存档时,一切正常,numpy正确加载后跟 sys.path

PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path = ['.', 'DLLs', 'Lib', 'Lib\\site-packages', 'Sources']");
PyRun_SimpleString("print sys.path");

编辑2 :另外,考虑检查 python27.dll 的确切版本 multiarray.pyd 是否已关联(根据其他帖子)关于类似的问题),事实证明它与我的不同 - 它是2.7.8。没问题,从.msi包中提取特定的python27.dll v2.7.8二进制文件并取代了我的2.7.13,但仍然没有运气。这绝对是 zipimport 模块的一部分。

enter image description here

1 个答案:

答案 0 :(得分:1)

最好的方法可能是暂时解压缩它。 zipimport 模块是 Python 用来从 zip 文件加载模块的模块,不幸的是它不允许导入动态编译代码(可能是出于安全考虑,与 PEP 273 一致):

<块引用>

任何文件都可能存在于 zip 存档中,但只有文件 *.py 和 .py[co] 可用于导入。 动态模块(.pyd、*.so)的 Zip 导入是不允许的

因为提供的轮子将是平台轮子,您还需要从 Cython 添加的 .so 文件名中删除平台扩展名,作为遵守 PEP 3149 的一部分。即,foo.cpython-XYm.so 需要重命名为 foo.so。 (由于您的问题是关于 Python 2,这并不适用,但它确实适用于 Python 3)

最后,解压后的文件夹必须是 added to the PYTHONPATH,如果它们还没有。