用C语言编写的Python模块传递参数 [英] Argument passing in Python module written in C

查看:64
本文介绍了用C语言编写的Python模块传递参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经开始用C语言编写Python模块,这让我非常着迷.我只是从一个简单的示例计算两点范数开始.代码看起来像这样,

I have been getting my feet wet with writing Python modules in C. I've started with just a simple example of computing the norm of two points. The code looks like this,

_norm.c

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

static char module_docstring[] =
    "This module provides an interface for computing the norm using C.";
static char norm_docstring[] =
    "Calculate the norm between two points";
static char norm2_docstring[] =
    "Calculate the square norm between two points. For efficiency.";

static PyObject *norm_norm(PyObject *self, PyObject *args);

static PyObject *norm_norm2(PyObject *self, PyObject *args);

static PyMethodDef module_methods[] = {
    {"norm", norm_norm, METH_VARARGS, norm_docstring},
    {"norm2", norm_norm2, METH_VARARGS, norm2_docstring},
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC init_norm(void) {
    PyObject *m = Py_InitModule3("_norm", module_methods, module_docstring);
    if (m == NULL)
        return;
}

static PyObject *norm_norm(PyObject *self, PyObject *args) {
   double x1, y1, x2, y2;
   /* Parse the input tuple */
   if (!PyArg_ParseTuple(args, "ddOOO", &x1, &y1, &x2, &y2))
       return NULL;

/* Call the external C function to compute the norm. */
double value = norm(x1, y1, x2, y2);

if (value < 0.0) {
    PyErr_SetString(PyExc_RuntimeError,
                    "Norm returned an impossible value.");
}
PyObject *ret = Py_BuildValue("d", value);
return ret;
}

norm.c

#include <math.h>

long double norm2(long double x1, long double y1, long double x2, long double y2) {
    long double xd = x2 - x1;
    long double yd = y2 - y1;
    return xd * xd + yd * yd;
}

long double norm(long double x1, long double y1, long double x2, long double y2) {
    return sqrt(norm2(x1, y1, x2, y2));
}

setup.py

from distutils.core import setup, Extension

setup(
    ext_modules=[Extension("_norm", ["_norm.c", "norm.c"])]
)

我这样构建程序包,

python setup.py build_ext --inplace

它编译没有问题.但是,当我尝试使用它时,会出现关于参数数量的错误.

And it compiles with no problems. However, when I try to use it I get an error about the number of arguments.

>>> import _norm
>>> _norm.norm(1,2,5,6)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: function takes exactly 5 arguments (4 given)

我猜可能与PyObject * norm_norm()的声明有关,因为它是通过* self传递的,但是我不确定这是否会影响我传递给Python端模块的参数事物.我将不胜感激.

I guess it might have something to do with the declaration of PyObject *norm_norm() because it gets passed *self, but I'm not sure if that should effect the arguments that I pass to the module on the Python side of things. I'd appreciate any help/suggestions.

推荐答案

PyArg_ParseTuple格式字符串中的问题.您正在尝试提取四个双精度参数,但是格式字符串用于两个双精度参数和三个任意Python对象("ddOOO").

The problem in the format string of PyArg_ParseTuple. You are trying to extract four double arguments, but the format string is for two double arguments and three arbitrary Python objects ("ddOOO").

对于您要尝试执行的操作,正确的格式字符串应为"dddd". 更改此

The correct format string should be "dddd" for what you are trying to do. Change this

if(!PyArg_ParseTuple(args,"ddOOO",& x1,& y1,& x2,& y2))

if (!PyArg_ParseTuple(args, "ddOOO", &x1, &y1, &x2, &y2))

if(!PyArg_ParseTuple(args,"dddd",& x1,& y1,& x2,& y2))

if (!PyArg_ParseTuple(args, "dddd", &x1, &y1, &x2, &y2))

这篇关于用C语言编写的Python模块传递参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆