У меня были проблемы с написанием модулей Python на C. Я начал с простого примера вычисления нормы двух точек. Код выглядит так,
_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;
}
норма.с
#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
И компилируется без проблем. Однако, когда я пытаюсь использовать его, я получаю сообщение об ошибке о количестве аргументов.
>>> 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. вещи. Буду признателен за любую помощь/предложения.