এই মেথড দেখায় কীভাবে একটি C এক্সটেনশন মডিউল থেকে নতুন পাইথন ক্লাস ডিফাইন করা যায়। ক্লাসের মেথডগুলো C-তে ইমপ্লিমেন্টেড থাকে, কিন্তু ক্লাসটি এখনও ইনস্ট্যানশিয়েট, সাবক্লাস এবং পাইথন থেকে এক্সটেন্ড করা যায়। একই টেকনিক ইনহেরিটেন্সের সাথে ব্যবহার করে একটি এক্সিস্টিং পাইথন ক্লাসকে C-তে লেখা মেথডlarla এক্সটেন্ড করা যায়। এই টেকনিকটিতে, PyClass_New-র প্রথম আর্গুমেন্ট NULL পাস করা হয়, যা দেখায় নতুন ক্লাসের কোনো বেস ক্লাস নেই। আমরা বেস ক্লাসের টাপল এই স্পটে পাস করি, এবং নরমাল পাইথন ইনহেরিটেন্স আচরণ পাই, যদিও আমাদের নতুন ক্লাস একটি C এক্সটেনশনে বিল্ড হয় পাইথন সোর্স কোডে না।
উদাহরণ
#include <Python.h>
static PyObject* Foo_init(PyObject *self, PyObject *args) {
printf("Foo.__init__ called\n");
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* Foo_doSomething(PyObject *self, PyObject *args) {
printf("Foo.doSomething called\n");
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef FooMethods[] = {
{"__init__", Foo_init, METH_VARARGS, "doc string"},
{"doSomething", Foo_doSomething, METH_VARARGS, "doc string"},
{0, 0},
};
static PyMethodDef ModuleMethods[] = {
{0, 0}
};
#ifdef __cplusplus
extern "C"
#endif
void initFoo(void) {
PyMethodDef *def;
/* নতুন মডিউল এবং ক্লাস অবজেক্ট তৈরি */
PyObject *module = Py_InitModule("Foo", ModuleMethods);
PyObject *moduleDict = PyModule_GetDict(module);
PyObject *classDict = PyDict_New();
PyObject *className = PyString_FromString("Foo");
PyObject *fooClass = PyClass_New(NULL, classDict, className);
PyDict_SetItemString(moduleDict, "Foo", fooClass);
Py_DECREF(classDict);
Py_DECREF(className);
Py_DECREF(fooClass);
/* ক্লাসে মেথড যোগ */
for (def = FooMethods; def->ml_name != NULL; def++) {
PyObject *func = PyCFunction_New(def, NULL);
PyObject *method = PyMethod_New(func, NULL, fooClass);
PyDict_SetItemString(classDict, def->ml_name, method);
Py_DECREF(func);
Py_DECREF(method);
}
}