Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

วิธี Attach C Method ให้ Existing Python Class

วิธีนี้แสดงวิธี Define Python Class ใหม่จาก C Extension Module Methods ของ Class ถูก Implement ใน C แต Class ยังสามารถ Instantiate, Subclass และ Extend จาก Python ได้ เทคนิคเดียวกันกับ Inheritance ยังสามารถใช้ Extend Existing Python Class ด้วย Methods ที่เขียนใน C ได้ ในเทคนิคนี้ Argument แรกของ PyClass_New ถูกส่งเป็น NULL แสดงว่า Class ใหม่ไม่มี Base Classes เราจึงส่ง Tuple ของ Base Classes ในตำแหน่งนี้ และจะได้ Normal Python Inheritance Behavior แม้ Class ใหม่จะถูกสร้างใน C Extension แทนที่จะเป็น Python Source Code

ตัวอย่าง

#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;
    /* create new module and class objects */
    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);

    /* add methods to class */
    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);
    }
}