问题
Okay here's the basic example from the Python website for a simple runpy.exe
to run Python scripts below. It works fine using Visual Studio 2015 on x64 Windows after referencing the Python includes and linking to python35.lib
for basic functions (the docs don't mention pyvenv.cfg
must be in the EXE directory). However, calling a script that imports NumPy
leads to this error ImportError: No module named 'numpy' Failed to load "eig"
only when using embedded python35.zip
, so how does one include NumPy
in an embedded Python EXE? I.e. I want to also "embed" NumPy (as a .zip, directory, .dll, or .pyd etc.). I've tried adding the NumPy includes and also linking to npymath.lib
but I get the same import error. I've also dug through some Cython wrapper code but haven't found a solution. Here is the Python embedded sample code:
#include <Python.h>
#include <iostream>
int main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pDict, *pFunc;
PyObject *pArgs, *pValue;
int i;
if (argc < 3) {
fprintf(stderr, "Usage: runpy pythonfile funcname [args]\n");
return 1;
}
Py_SetPath(L"python35.zip"); //this is in the current directory
Py_Initialize();
pName = PyUnicode_DecodeFSDefault(argv[1]);
/* Error checking of pName left out */
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, argv[2]);
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(argc - 3);
for (i = 0; i < argc - 3; ++i) {
pValue = PyLong_FromLong(atoi(argv[i + 3]));
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
return 1;
}
/* pValue reference stolen here: */
PyTuple_SetItem(pArgs, i, pValue);
}
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL) {
printf("Result of call: %ld\n", PyLong_AsLong(pValue));
Py_DECREF(pValue);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr, "Call failed\n");
return 1;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
return 1;
}
Py_Finalize();
return 0;
}
Embed file is here: https://www.python.org/ftp/python/3.5.2/python-3.5.2-embed-amd64.zip, python35.zip
inside the archive. Here is the simple test script (runpy eig eig 10
to test - note if you don't embed Python35.zip
and have NumPy
/ SciPy
installed it WILL run):
eig.py
import numpy as np
from scipy import linalg
def eig(a):
c = np.random.rand(a,a)*100
c = np.corrcoef(c)
print('You are taking the eigsh of a ', a, '^2 matrix')
e, f = linalg.eig(c)
return print('Eigvals are: ',np.diag(f))
Anyone know how to fix this issue? Much appreciated.
Update: Here's the compiled version x64 Python 3.5 Windows NumPy SciPy and Pandas with Intel MKL included: https://www.dropbox.com/sh/2smbgen2i9ilf2e/AADI8A3pCAFU-EqNLTbOiUwJa?dl=0
回答1:
This does not work because numpy is not in the zipfile python35.zip
.
The runpy-program sets the path to python35.zip
: It is thus the only path in the Pythonpath for this programs exception...
You have to add the parent-folder of your local numpy-folder also to the Pythonpath to make it working.
来源:https://stackoverflow.com/questions/38333320/embedded-python-does-not-work-pointing-to-python35-zip-with-numpy-how-to-fix