标签: python-c-api

致命错误:Python.h:没有这样的文件或目录

我正在尝试使用C扩展文件构建共享库,但首先我必须使用以下命令生成输出文件:

gcc -Wall utilsmodule.c -o Utilc
Run Code Online (Sandbox Code Playgroud)

执行命令后,我收到此错误消息:

utilsmodule.c:1:20:致命错误:Python.h:没有这样的文件或目录编译终止.

事实上我已经通过互联网尝试了所有建议的解决方案,但问题仍然存在...我也没有问题Python.h.我设法在我的机器上找到该文件......任何人在遇到同样的问题之前?

python gcc python-c-api python-c-extension

1042
推荐指数
27
解决办法
80万
查看次数

Python(和Python C API):__ new__与__init__

我要问的问题似乎是Python使用__new__和__init__的重复但是无论如何,我还不清楚到底是什么__new____init__它之间的实际区别.

在你急于告诉我__new__是用于创建对象并且__init__用于初始化对象之前,让我说清楚:我明白了. 事实上,这种区别对我来说是很自然的,因为我在C++中有经验,我们有新的贴图,它同样将对象分配与初始化分开.

Python的C API教程解释它是这样的:

新成员负责创建(而不是初始化)该类型的对象.它在Python中作为__new__()方法公开.... 实现新方法的一个原因是确保实例变量的初始值.

所以,是的 - 我得到了什么__new__,但尽管如此,我仍然不明白为什么它在Python中有用.给出的示例说,__new__如果要"确保实例变量的初始值" ,这可能很有用.那么,这究竟是什么意思__init__呢?

在C API教程中,显示​​了一个示例,其中创建了一个新类型(称为"Noddy"),并__new__定义了Type的函数.Noddy类型包含一个名为的字符串成员first,并且此字符串成员初始化为空字符串,如下所示:

static PyObject * Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    .....

    self->first = PyString_FromString("");
    if (self->first == NULL)
    {
       Py_DECREF(self);
       return NULL;
    }

    .....
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果没有__new__此处定义的方法,我们必须使用PyType_GenericNew,它只是将所有实例变量成员初始化为NULL.因此,该__new__方法的唯一好处是实例变量将以空字符串开头,而不是NULL. 但是为什么这个有用,因为如果我们关心确保我们的实例变量被初始化为某个默认值,我们可以在 …

c python python-c-api

118
推荐指数
5
解决办法
3万
查看次数

如何在Python C-API中动态创建派生类型

假设我们有关于为Python编写C扩展模块Noddy教程中定义的类型.现在我们要创建一个派生类型,只覆盖它的__new__()方法Noddy.

目前我使用以下方法(为了便于阅读而删除了错误检查):

PyTypeObject *BrownNoddyType =
    (PyTypeObject *)PyType_Type.tp_alloc(&PyType_Type, 0);
BrownNoddyType->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
BrownNoddyType->tp_name = "noddy.BrownNoddy";
BrownNoddyType->tp_doc = "BrownNoddy objects";
BrownNoddyType->tp_base = &NoddyType;
BrownNoddyType->tp_new = BrownNoddy_new;
PyType_Ready(BrownNoddyType);
Run Code Online (Sandbox Code Playgroud)

这有效,但我不确定它是不是正确的方法.我本来期望我也必须设置Py_TPFLAGS_HEAPTYPE标志,因为我在堆上动态分配类型对象,但这样做会导致解释器中出现段错误.

我还想过明确地type()使用PyObject_Call()或类似地调用,但我放弃了这个想法.我需要将函数包装BrownNoddy_new()在Python函数对象中并创建一个映射__new__到此函数对象的字典,这看起来很愚蠢.

最好的方法是什么?我的方法是否正确?我错过了接口功能吗?

更新

python-dev邮件列表(1) (2)上的相关主题有两个主题.从这些线程和一些实验中我推断出Py_TPFLAGS_HEAPTYPE除非通过调用分配类型,否则我不应该设置type().这些线程中有不同的建议是手动分配类型还是调用更好type().如果我知道推荐的方法来包装应该插入tp_new插槽的C函数,我会对后者感到满意.对于常规方法,这一步很简单 - 我可以PyDescr_NewMethod()用来获得一个合适的包装器对象.我不知道如何为我的__new__()方法创建这样的包装器对象- 也许我需要未记录的函数PyCFunction_New()来创建这样的包装器对象.

python derived-class python-2.x python-c-api

72
推荐指数
2
解决办法
4284
查看次数

从C/C++调用python方法,并提取其返回值

我想调用一个在C语言的python模块中定义的自定义函数.我有一些初步代码可以做到这一点,但它只是将输出打印到stdout.

mytest.py

import math

def myabs(x):
    return math.fabs(x)
Run Code Online (Sandbox Code Playgroud)

TEST.CPP

#include <Python.h>

int main() {
    Py_Initialize();
    PyRun_SimpleString("import sys; sys.path.append('.')");
    PyRun_SimpleString("import mytest;");
    PyRun_SimpleString("print mytest.myabs(2.0)");
    Py_Finalize();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如何将返回值提取到C double并在C中使用它?

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

49
推荐指数
4
解决办法
6万
查看次数

如何使用Python C API创建生成器/迭代器?

如何使用Python C API复制以下Python代码?

class Sequence():
    def __init__(self, max):
        self.max = max
    def data(self):
        i = 0
        while i < self.max:
            yield i
            i += 1
Run Code Online (Sandbox Code Playgroud)

到目前为止,我有这个:

#include <Python/Python.h>
#include <Python/structmember.h>

/* Define a new object class, Sequence. */
typedef struct {
    PyObject_HEAD
    size_t max;
} SequenceObject;

/* Instance variables */
static PyMemberDef Sequence_members[] = {
    {"max", T_UINT, offsetof(SequenceObject, max), 0, NULL},
    {NULL} /* Sentinel */
};

static int Sequence_Init(SequenceObject *self, PyObject *args, PyObject *kwds)
{
    if (!PyArg_ParseTuple(args, "k", &(self->max))) { …
Run Code Online (Sandbox Code Playgroud)

c python iterator generator python-c-api

43
推荐指数
2
解决办法
8375
查看次数

使用Python的C API创建对象

假设我的对象布局定义为:

typedef struct {
    PyObject_HEAD
    // Other stuff...
} pyfoo;
Run Code Online (Sandbox Code Playgroud)

...和我的类型定义:

static PyTypeObject pyfoo_T = {
    PyObject_HEAD_INIT(NULL)
    // ...

    pyfoo_new,
};
Run Code Online (Sandbox Code Playgroud)

如何pyfoo在C扩展中的某个位置创建新实例?

c python python-embedding python-c-api python-extensions

41
推荐指数
1
解决办法
1万
查看次数

Py_INCREF/DECREF:何时

说明以下内容是正确的:

  • 如果在C函数中创建了Python对象,但该函数没有返回它,INCREF则不需要,但是a DECREF.

  • [false]如果函数确实返回了它,你需要INCREF在接收返回值的函数中.[/ false]

  • 当分配了C类型的变量作为属性,如double,int等等,给Python对象,没有INCREFDECREF需要.

  • 将Python对象作为属性分配给其他Python对象,如下所示:

    PyObject *foo;
    foo = bar // A Python object
    tmp = self->foo;
    Py_INCREF(foo);
    self->foo = foo;
    Py_XDECREF(tmp);
    //taken from the manual, but it is unclear if this works in every situation
    
    Run Code Online (Sandbox Code Playgroud)

编辑: - >我可以在任何情况下安全地使用它吗?(没有碰到一个导致我问题的地方)

  • Python对象的dealloc需要DECREF用于其作为属性的每个其他Python对象,但不适用于C类型的属性.

编辑

'C type as a attribute'是指bar和baz:

typedef struct {
    PyObject_HEAD
    PyObject *foo;
    int bar;
    double baz;
} FooBarBaz;
Run Code Online (Sandbox Code Playgroud)

python python-c-api

36
推荐指数
1
解决办法
1万
查看次数

如何在c ++代码中捕获python stdout

我有一个程序,在它运行期间有时需要调用python来执行某些任务.我需要一个调用python并捕获pythons stdout并将其放入某个文件的函数.这是函数的声明

  pythonCallBackFunc(const char* pythonInput)
Run Code Online (Sandbox Code Playgroud)

我的问题是捕获给定命令(pythonInput)的所有python输出.我没有python API的经验,我不知道什么是正确的技术来做到这一点.我尝试过的第一件事是使用Py_run_SimpleString重定向python的sdtout和stderr,这是我编写的代码的一些例子.

#include "boost\python.hpp"
#include <iostream>

void pythonCallBackFunc(const char* inputStr){   

    PyRun_SimpleString(inputStr); 
}


int main () {
    ...
   //S0me outside functions does this
   Py_Initialize();
   PyRun_SimpleString("import sys");
   PyRun_SimpleString("old_stdout = sys.stdout");
   PyRun_SimpleString("fsock = open('python_out.log','a')");
   PyRun_SimpleString("sys.stdout = fsock");
   ...

   //my func   
   pythonCallBackFunc("print 'HAHAHAHAHA'");
   pythonCallBackFunc("result = 5");
   pythonCallBackFunc("print result");

   pythonCallBackFunc("result = 'Hello '+'World!'");
   pythonCallBackFunc("print result");

   pythonCallBackFunc("'KUKU '+'KAKA'");
   pythonCallBackFunc("5**3");

   pythonCallBackFunc("prinhghult");

   pythonCallBackFunc("execfile('stdout_close.py')");
   ... 

   //Again anothers function code
   PyRun_SimpleString("sys.stdout = old_stdout");
   PyRun_SimpleString("fsock.close()");

   Py_Finalize();
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?此外,由于某种原因PyRun_SimpleString在得到一些数学表达式时什么都不做,例如PyRun_SimpleString("5**3")什么都不打印(python …

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

25
推荐指数
3
解决办法
1万
查看次数

停止嵌入式Python

我正在将Python解释器嵌入到C程序中.但是,可能会发生这样的情况:运行某些python脚本时PyRun_SimpleString()会遇到无限循环或执行太长时间.考虑PyRun_SimpleString("while 1: pass");在阻止主程序阻止我认为我可以在一个线程中运行解释器.

如何停止在线程中运行的嵌入式解释器中执行python脚本而不会终止整个过程?

是否可以将异常传递给解释器?我应该将脚本包装在其他可以收听信号的脚本下吗?

PS:我可以在一个单独的过程中运行python,但这不是我想要的 - 除非它是最后的手段......


更新:

所以,它现在有效.再次感谢Denis Otkidach!

如果我看到这一点,你必须做两件事:告诉解释器停止并return -1在与PyRun_SimpleString()运行的同一个线程中.

要停止,有一些可能性:PyErr_SetString(PyExc_KeyboardInterrupt, "...")或者PyErr_SetInterrupt()- 第一个可能让Python运行更多指令然后停止,后者立即停止执行.

return -1使用Py_AddPendingCall()注入一个函数调用成Python执行.自2.7和3.1版以来,文档提到它,但它也运行在早期的Pythons上(这里是2.6).从2.7和3.1它也应该是线程安全的,这意味着你可以在不获取GIL(?)的情况下调用它.

所以可以重写下面的例子:

int quit() {
    PyErr_SetInterrupt();
    return -1;
}
Run Code Online (Sandbox Code Playgroud)

python multithreading process embedded-language python-c-api

23
推荐指数
1
解决办法
5048
查看次数

将布尔值传递给Python C扩展的"正确"方法是什么?

这是python文档(http://docs.python.org/extending/extending.html)中的一个简单示例:

static PyObject *
spam_system(PyObject *self, PyObject *args)
{
    const char *command;
    int sts;

    if (!PyArg_ParseTuple(args, "s", &command))
        return NULL;
    sts = system(command);
    return Py_BuildValue("i", sts);
}
Run Code Online (Sandbox Code Playgroud)

如果我想将另一个布尔参数传递给函数 - 这是什么"正确"的方法呢?

似乎没有传递给PyArg_ParseTuple()的bool选项.所以我想到了以下几点:

  1. 读取一个整数并只使用该值(因为bool是int的子类)
  2. 在整数上调用PyBool_FromLong()
  3. 读取和对象并调用PyBool_Check()来验证它是一个bool
  4. 也许有一种方法可以获得任何类型的变量并获得其真值(即空数组将是假数据等),这是python函数通常所做的.

这些中哪一个更好?其他选择?

python python-c-api python-c-extension

23
推荐指数
3
解决办法
9521
查看次数