मैं यह समझने की कोशिश कर रहा हूं कि सी एक्सटेंशन मॉड्यूल में एक चर (और शायद) फ़ंक्शन में बड़ी संख्या में तर्क होने के लिए कैसे किया जाता है।तर्कों की परिवर्तनीय संख्या के साथ पायथन एक्सटेंशन मॉड्यूल
PyArg_ParseTuple के बारे में पढ़ना ऐसा लगता है कि आपको यह जानना है कि कितने स्वीकार करना है, कुछ अनिवार्य और कुछ वैकल्पिक लेकिन सभी अपने स्वयं के चर के साथ। मैं उम्मीद कर रहा था कि PyArg_UnpackTuple इसे संभालने में सक्षम होगा लेकिन ऐसा लगता है कि जब मैं गलत तरीके से प्रतीत होता हूं तो इसे बस कोशिश करता हूं और इसका उपयोग करता हूं।
उदाहरण के रूप में निम्न पायथन कोड लें जो कोई एक्सटेंशन मॉड्यूल (सी में) बनाना चाहता है।
def hypot(*vals):
if len(vals) !=1 :
return math.sqrt(sum((v ** 2 for v in vals)))
else:
return math.sqrt(sum((v ** 2 for v in vals[0])))
इस तर्क के किसी भी संख्या के साथ बुलाया जा सकता है या hypot(3,4,5)
से अधिक दोहराया,, hypot([3,4,5])
, और hypot(*[3,4,5])
सभी एक ही जवाब दे।
मेरी सी समारोह की शुरुआत की तरह इस
static PyObject *hypot_tb(PyObject *self, PyObject *args) {
// lots of code
// PyArg_ParseTuple or PyArg_UnpackTuple
}
कई yasar11732 लिए सोचता है कि लग रहा है। यहां अगले व्यक्ति के लिए एक पूरी तरह से काम कर रहे विस्तार मॉड्यूल (_toolboxmodule.c) है जो कि किसी भी संख्या या पूर्णांक तर्कों को लेता है और उन तर्कों (खराब नाम के साथ) की एक सूची देता है। एक खिलौना लेकिन दिखाता है कि क्या किया जाना चाहिए।
#include <Python.h>
int ParseArguments(long arr[],Py_ssize_t size, PyObject *args) {
/* Get arbitrary number of positive numbers from Py_Tuple */
Py_ssize_t i;
PyObject *temp_p, *temp_p2;
for (i=0;i<size;i++) {
temp_p = PyTuple_GetItem(args,i);
if(temp_p == NULL) {return NULL;}
/* Check if temp_p is numeric */
if (PyNumber_Check(temp_p) != 1) {
PyErr_SetString(PyExc_TypeError,"Non-numeric argument.");
return NULL;
}
/* Convert number to python long and than C unsigned long */
temp_p2 = PyNumber_Long(temp_p);
arr[i] = PyLong_AsUnsignedLong(temp_p2);
Py_DECREF(temp_p2);
}
return 1;
}
static PyObject *hypot_tb(PyObject *self, PyObject *args)
{
Py_ssize_t TupleSize = PyTuple_Size(args);
long *nums = malloc(TupleSize * sizeof(unsigned long));
PyObject *list_out;
int i;
if(!TupleSize) {
if(!PyErr_Occurred())
PyErr_SetString(PyExc_TypeError,"You must supply at least one argument.");
return NULL;
}
if (!(ParseArguments(nums, TupleSize, args)) {
free(nums);
return NULL;
}
list_out = PyList_New(TupleSize);
for(i=0;i<TupleSize;i++)
PyList_SET_ITEM(list_out, i, PyInt_FromLong(nums[i]));
free(nums);
return (PyObject *)list_out;
}
static PyMethodDef toolbox_methods[] = {
{ "hypot", (PyCFunction)hypot_tb, METH_VARARGS,
"Add docs here\n"},
// NULL terminate Python looking at the object
{ NULL, NULL, 0, NULL }
};
PyMODINIT_FUNC init_toolbox(void) {
Py_InitModule3("_toolbox", toolbox_methods,
"toolbox module");
}
अजगर में तो यह है:
>>> import _toolbox
>>> _toolbox.hypot(*range(4, 10))
[4, 5, 6, 7, 8, 9]
आप हमें क्यों बताऊँ कि आप से दुर्घटनाओं हो रही * '' PyArg_ साथ कठिनाई हो रही कार्य /, और फिर हमें के अलावा सब कुछ दिखाने आप 'PyArg_ *' फ़ंक्शंस का उपयोग कैसे करते हैं? –
आपको पार्सिंग (नल लौटाया गया) के दौरान त्रुटियों के दौरान त्रुटियों के दौरान त्रुटियों के दौरान त्रुटियों के दौरान त्रुटियों को वापस करने के लिए त्रुटियों के दौरान त्रुटियों के दौरान त्रुटियों को वापस करने के लिए त्रुटियों के अंदर एक पैरा कथन दर्ज करना चाहिए। अन्यथा आप तर्क पार्सिंग के दौरान त्रुटियों को दबाएंगे। – yasar
हां, हाँ आप सही हैं। मैं पोस्ट संपादित करूंगा। –