Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Cách gắn phương thức C vào class Python hiện có?

Phương pháp này chỉ cách định nghĩa Python class mới từ C extension module. Method của class implement bằng C, nhưng class vẫn có thể instantiate, subclass, extend từ Python. Kỹ thuật tương tự với inheritance cũng dùng để extend class Python hiện có với method viết bằng C. Trong kỹ thuật này, tham số đầu PyClass_New truyền NULL (class mới không có base class). Ta truyền tuple base classes ở vị trí này, sẽ có behavior inheritance Python bình thường, dù class mới build từ C extension chứ không phải Python source.

Ví dụ

#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);
    }
}