Computer >> Máy Tính >  >> Lập trình >> Python

Làm cách nào để đính kèm một phương thức C vào lớp Python hiện có?


Phương thức này cho biết cách xác định một lớp Python mới từ mô-đun mở rộng C. Các phương thức của lớp được triển khai bằng C, nhưng lớp vẫn có thể được khởi tạo, phân lớp và mở rộng từ Python. Kỹ thuật tương tự với kế thừa cũng có thể được sử dụng để mở rộng một lớp Python hiện có với các phương thức được viết bằng C. Trong kỹ thuật này, đối số đầu tiên cho PyClass_New được truyền là NULL, cho thấy rằng lớp mới không có lớp cơ sở. Sau đó, chúng tôi chuyển hàng loạt các lớp cơ sở vào vị trí này và chúng tôi sẽ nhận được hành vi kế thừa Python bình thường, mặc dù lớp mới của chúng tôi đang được xây dựng trong một phần mở rộng C thay vì trong mã nguồn Python.

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(  )
{
    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);
    }
}