标签: python-embedding

"AttributeError:'module'对象在使用Python.h时没有属性'argv'"

搞乱Python.h时我遇到了这个错误:

AttributeError: 'module' object has no attribute 'argv'
Run Code Online (Sandbox Code Playgroud)

C++代码:

#include "stdafx.h"  
#include "C:/Python27/include/Python.h"  
#include <iostream>  

using namespace std;  


int main()  
{
    Py_Initialize();
    PyRun_SimpleString("import sys\nprint sys.argv[0]");
}
Run Code Online (Sandbox Code Playgroud)

在Python中是:

import sys
print sys.argv[0]
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

c++ python python-embedding python-c-api

11
推荐指数
1
解决办法
6874
查看次数

当从C++应用程序中的嵌入式Python调用时,Numpy导入在多数组扩展库上失败

我正在运行一个C++应用程序,它尝试使用https://docs.python.org/3.5/extending/embedding.html函数调用来运行python .这是应用程序错误消息管道给我的错误.

class'ImportError':导入多阵列numpy扩展模块失败.您很可能正在尝试导入失败的numpy版本.如果您正在使用numpy git repo,请尝试git clean -xdf(删除不受版本控制的所有文件).否则重新安装numpy.

原始错误是:/usr/local/lib/python3.5/site-packages/numpy/core/multiarray.cpython-35m-x86_64-linux-gnu.so:undefined symbol:PyExc_UserWarning

我很困惑,因为只有当我在C++中嵌入Python时才会出现这种情况,因为当我通过解释器使用它时导入工作.我对答案更感兴趣,这个答案增加了我的理解,而不是快速做到这一点或做了那个修复.我列出了下面的一些系统/问题信息,以及我正在考虑发布关于同一主题的一些其他问题.任何指导表示赞赏!

系统/问题信息:

  • Ubuntu 16.04,64位
  • 使用enabled-shared编译的Python 3.5.5
  • numpy导入在解释器中工作(python3.exe和python3.5.exe)
  • 我已经确定了PySys_SetPath()设置相同的sys.path从翻译的输出:import sys,sys.path
  • 我可以导入其他模块,如PIL和datetimeutil; 然而,numpy和pandas是不可导入的(熊猫使用numpy或似乎)
  • 嵌入式Python使用下面的命令:Py_Import_Import(),Py_Initialize()(我确信它只能调用一次.)等,但它并没有得到解释的全局锁.
  • 该应用程序使用CMake构建系统构建,该系统为我的系统编译MakeFiles.
  • 使用pip3.5 install numpy命令使用pip 9.0.0安装numpy-1.14.2
  • 导致此错误的python脚本有一行:import numpy...
  • 我没有我要导入文件的.zip文件.
  • 嵌入在C++中的Python使用的.exe位于/ usr/local/bin/python3(使用Py_GetProgramName()来确定这一点).此.exe链接到libpython3.5m.so.1.0,缺少的符号位于libpython3.5m.so.1.0(运行nm)
  • ldd on multiarray.cpython-35m-x86_64-linux-gnu.so显示:

    ldd multiarray.cpython-35m-x86_64-linux-gnu.so

    linux-vdso.so.1 =>(0x00007ffd9e36b000)

    libopenblasp-r0-39a31c03.2.18.so => /usr/local/lib/python3.5/site-packages/numpy/core/./../.libs/libopenblasp-r0-39a31c03.2.18.so(0x00007fdbe149b000)

    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6(0x00007fdbe1192000)

    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0(0x00007fdbe0f75000)libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6(0x00007fdbe0bab000)/ lib64 /ld-linux-x86-64.so.2(0x00007fdbe3ed5000)

    libgfortran-ed201abd.so.3.0.0 => /usr/local/lib/python3.5/site-packages/numpy/core/./../.libs/libgfortran-ed201abd.so.3.0.0(0x00007fdbe08b1000)

我可以/可能会尝试通过不同的方式重新安装numpy,但我无法跟踪为什么这可能会起作用.

在这一点上,我假设我的知识存在一些漏洞.我已经看过很多关于在C++中嵌入Python时无法导入多阵列组件和numpy的类似帖子; 但是,要么它们都不符合我的具体情况,要么就像我说的那样存在漏洞.以下是我可能会问的一个子问题列表,如果没有人在这个设置中看到任何明显有关的内容.如果我问他们(在我擦亮之后),我可能会用链接更新问题.

  • numpy multiarray.so如何链接到pythonX.X.so以进行符号解析?ldd似乎没有暗示它曾经做过.在这个链接上问这个问题
  • 在这个解决问题的CMake不相关的问题的问题问及18年4月12日,并回答了在18年4月16日.
  • 在.bashrc中设置PYTHONPATH似乎不会更新Py_GetPath()返回的内容,我不得不通过与sys.path不同的方法在site-packages中添加导入.它可能只更新不影响C++的bash脚本环境变量. …

c++ python numpy python-embedding python-3.x

11
推荐指数
1
解决办法
817
查看次数

在WinForms应用程序中嵌入IronPython并中断执行

背景

我的问题

  • 用户需要中断其代码的执行
  • 换句话说,当从cmdline运行Python或IronPython时,他们需要点击CTRL-C以暂停执行的能力
  • 我想在winform中添加一个按钮,当按下时会暂停执行,但我不知道该怎么做.

我的问题

  • 如何按下"停止"按钮实际上会停止使用输入的IronPython代码的执行?

笔记

  • 注意:我不想简单地丢弃"会话" - 我仍然希望用户能够与会话进行交互并访问在暂停之前可用的任何结果.
  • 我假设我需要在一个单独的线程中执行此操作,正确执行此操作的任何指导或示例代码将不胜感激.

ironpython python-embedding

10
推荐指数
1
解决办法
1590
查看次数

(Python C API)PyRun_StringFlags缺少内置函数?

我想在我的宠物项目中嵌入一些python.我已将问题减少到以下代码:

#include <Python.h>
#include "iostream"

int main(int argc, char *argv[])
{
    Py_Initialize();

    PyObject *globals = Py_BuildValue("{}");
    PyObject *locals = Py_BuildValue("{}");

    PyObject *string_result = PyRun_StringFlags(
        "a=5\n"
        "s='hello'\n"
        "d=dict()\n"
        ,
        Py_file_input, globals, locals, NULL);
    if ( PyErr_Occurred() ) {PyErr_Print();PyErr_Clear();return 1;}
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

(我知道我没有清理任何参考文献.这是一个例子.)

它可以编译

c++ $(python-config --includes) $(python-config --libs) test.cpp -o test
Run Code Online (Sandbox Code Playgroud)

如果我运行它,我会收到以下错误:

$ ./test 
Traceback (most recent call last):
  File "<string>", line 3, in <module>
NameError: name 'dict' is not defined
Run Code Online (Sandbox Code Playgroud)

看来内置函数没有加载.我也import什么都没有.我明白了__import__.如何加载丢失的模块或我遗漏的任何内容?

谢谢.

python python-embedding python-c-api

10
推荐指数
2
解决办法
1529
查看次数

将matplotlib图表嵌入到Qt/C++应用程序中

我正在开发一个Qt/C++中面向数学的GUI应用程序,并希望嵌入一个Python脚本,包括NumPy和Matplotlib.使用Python C API,我终于设法运行脚本,从Python变量中检索值,包括NumPy数组等.但是我将Matplotlib图表绘制到我的Qt/C++应用程序中失败了.

最好说,我已经设法使用Python脚本将图表的RGBA缓冲区保存到变量,然后将变量的值作为缓冲区类型的PyObject获取,获取缓冲区并将其转换为QImage,然后转换为QPixmap,最后放入它进入QLabel并显示它.

但我仍然缺少它的交互行为,调整大小等等虽然看起来它可以通过将Qt鼠标事件转发到figure.canvas.button_press_event来完成,但它变得过于复杂......所以我总结了我不明白这些原则Python嵌入得足够好.我错过了一些明显的东西.

我发现了一些将matplotlib图表嵌入PyQt或PySide(即用Python编写)应用程序的示例,其中我看到了类似QMainWindow.setCentralWidget(canvas)或layout.addWidget(canvas)的内容.这里的canvas是FigureCanvasQTAgg对象(http://matplotlib.org/api/backend_qt4agg_api.html).

这表明canvas继承自QWidget.但是,当我尝试使用Python的C API在C++代码中模仿它时,我只是用PyObject*画布结束,不知道如何将它转换为QWidget.这是我没有重要步骤的片段:

//draw a figure in Python script called from C++ app
PyRun_SimpleString("import matplotlib\n"
"matplotlib.use('Qt4agg')\n" //use Qt4 backend
"import pylab\n"
"pylab.plot(randn(10))\n" //plot something
"fig = pylab.gcf()\n" //take current figure
"canvas = fig.canvas" //canvas is of FigureCanvasQTAgg type

//get canvas as PyObject
PyObject* m = PyImport_AddModule("__main__");
PyObject* canvas = PyObject_GetAttrString(m, "canvas");
//from what I know, canvas is a PyObject wrapped around an object derived from QWidget

//...
//... here I do not know …
Run Code Online (Sandbox Code Playgroud)

python qt pyqt matplotlib python-embedding

10
推荐指数
1
解决办法
2392
查看次数

Python解释器作为c ++类

我正在努力将python嵌入到c ++中.在某些特殊情况下,我需要在同一个线程中有两个独立的解释器实例.

我可以将Python解释器包装到c ++类中并从两个或更多类实例中获取服务吗?

c++ python multithreading python-embedding python-c-api

9
推荐指数
2
解决办法
3138
查看次数

是否可以在运行时修改PYTHONPATH?

我有一个动态链接到Python解释器的C++应用程序.我希望能够从特定目录导入python模块.我想修改我的进程的PYTHONPATH,以便sys.path将包含我添加到PYTHONPATH的路径.根据这个文档,这似乎是它的工作方式:

http://docs.python.org/c-api/intro.html#embedding-python

但是,当我从Python-land打印sys.path时,它具有PYTHONPATH的原始内容而不是我设置的内容.这是我正在做的一个例子(使用Boost.Python):

int main(int argc, char* argv[])
{
  _putenv_s("PYTHONPATH", "C:\\source\\\\modules");
  Py_Initialize();
  object main = import("__main__");
  object global = (main.attr("__dict__"));
  exec("import sys\nprint sys.path"), global, global);
}
Run Code Online (Sandbox Code Playgroud)

PS - 我知道还有其他方法可以实现我的目标,但这不是我所要求的.我想知道为什么Py_Initialize()在设置sys.path时不使用PYTHONPATH的当前值.或许我误解了它应该如何运作?

c++ python python-embedding python-c-api boost-python

9
推荐指数
1
解决办法
7649
查看次数

为什么PyImport_Import无法从当前目录加载模块?

我正在尝试运行嵌入示例,我无法从当前工作目录加载模块,除非我明确地将其添加到sys.path它然后工作:

PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\".\")"); 
Run Code Online (Sandbox Code Playgroud)

Python不应该在当前目录中查找模块吗?

Edit1:尝试导入模块:

Py_Initialize();
PyRun_SimpleString("import multiply"); 
Run Code Online (Sandbox Code Playgroud)

它仍然失败,出现以下错误:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named multiply
Run Code Online (Sandbox Code Playgroud)

Edit2:来自sys.path 文档:

如果脚本目录不可用(例如,如果以交互方式调用解释器或者从标准输入读取脚本),path [0] 是空字符串,它指示Python首先搜索当前目录中的模块.

不确定它是什么意思不可用,但如果我打印sys.path[0]它不是空的:

/usr/lib/pymodules/python2.7
Run Code Online (Sandbox Code Playgroud)

python linux python-embedding python-2.7

9
推荐指数
1
解决办法
8128
查看次数

嵌入式Python 2.7.2从用户定义的目录导入模块

我将Python嵌入到将具有已定义API的C/C++应用程序中.

应用程序需要实例化脚本中定义的类,这些类的结构大致如下:

class userscript1:
    def __init__(self):
        ##do something here...

    def method1(self):
        ## method that can be called by the C/C++ app...etc
Run Code Online (Sandbox Code Playgroud)

我过去曾经管理过(为了概念验证)使用以下类型的代码完成这项工作:

PyObject* pName = PyString_FromString("userscript.py");
PyObject* pModule = PyImport_Import(pName);
PyObject* pDict = PyModule_GetDict(pModule);
PyObject* pClass = PyDict_GetItemString(pDict, "userscript");
PyObject* scriptHandle = PyObject_CallObject(pClass, NULL);
Run Code Online (Sandbox Code Playgroud)

现在我处于更多的生产环境中,这在PyImport_Import行失败了 - 我想这可能是因为我正在尝试将目录添加到脚本名称中,例如

PyObject* pName = PyString_FromString("E:\\scriptlocation\\userscript.py");
Run Code Online (Sandbox Code Playgroud)

现在,为了让您了解我尝试过的内容,我尝试在所有这些调用之前修改系统路径以使其搜索此模块.基本上尝试以编程方式修改sys.path:

PyObject* sysPath = PySys_GetObject("path");
PyObject* path = PyString_FromString(scriptDirectoryName);
int result = PyList_Insert(sysPath, 0, path);
Run Code Online (Sandbox Code Playgroud)

这些行运行正常,但对我的代码工作没有任何影响.显然,我的真实代码有一大堆错误检查,我已经排除了所以不要担心!

所以我的问题是:如何将嵌入式解释器适当地引导到我的脚本中以便我可以实例化类?

c c++ python python-embedding python-c-api

8
推荐指数
1
解决办法
4029
查看次数

运行Python 3.5解释器需要哪些标准库模块?

这是一个CPython程序,试图用空的初始化解释器sys.path:

#include <Python.h>

int main(int argc, char** argv)
{
    wchar_t* program = NULL;
    wchar_t* sys_path = NULL;

    Py_NoSiteFlag = 1;

    program = Py_DecodeLocale(argv[0], NULL);
    Py_SetProgramName(program);

    sys_path = Py_DecodeLocale("", NULL);
    Py_SetPath(sys_path);

    Py_Initialize();

    PyMem_RawFree(program);    
    PyMem_RawFree(sys_path);
    Py_Finalize();
}
Run Code Online (Sandbox Code Playgroud)

执行上述程序会引发以下错误:

Fatal Python error: Py_Initialize: Unable to get the locale encoding
ImportError: No module named 'encodings'

Current thread 0x00007ffff7fc6700 (most recent call first):
Signal: SIGABRT (Aborted)
Run Code Online (Sandbox Code Playgroud)

那么除了encodings包之外,Python 3.5标准库中的哪些包和模块是运行Python 3.5解释器所必需的?在我的文档中似乎没有这些信息.

python python-embedding python-3.x python-internals python-3.5

8
推荐指数
1
解决办法
512
查看次数