What is the PyClass_New equivalent in Python 3?

I previously created several Python classes using the C API. When I am about to build an old project with Python 3+, it gives the following compilation error

PyClass_New was not declared in this scope
Py_InitModule was not declared in this scope

What are the equivalents?

PyObject *pClassDic = PyDict_New();
PyObject *pClassName = PyBytes_FromString("MyClass");
PyObject *pClass = PyClass_New(NULL, pClassDic, pClassName);
+6
source share
2 answers

If you don't want to sort through the problems with customizing your object and types of structures, you should be able to create a new class by calling Python type(name, bases, dict)from C:

PyObject *pClassName = PyBytes_FromString("MyClass");
PyObject *pClassBases = PyTuple_New(0); // An empty tuple for bases is equivalent to `(object,)`
PyObject *pClassDic = PyDict_New();

// pClass = type(pClassName, pClassBases, pClassDic)
PyObject *pClass = PyObject_CallFunctionObjArgs(PyType_Type, pClassName, pClassBases, pClassDic, NULL);

Py_CLEAR(pClassName);
Py_CLEAR(pClassBases);
Py_CLEAR(pClassDic);
+4
source

to complete the answer from 'cpburnz', here is a function that creates a class object and adds methods:

PyObject *createClassObject(const char *name, PyMethodDef methods[])
{
    PyObject *pClassName = PyUnicode_FromString(name);
    PyObject *pClassBases = PyTuple_New(0); // An empty tuple for bases is equivalent to '(object,)'
    PyObject *pClassDic = PyDict_New();


    PyMethodDef *def;
    // add methods to class 
    for (def = methods; def->ml_name != NULL; def++)
    {
        printf("     add method %s\n", def->ml_name);
        PyObject *func = PyCFunction_New(def, NULL);
        PyObject *method = PyInstanceMethod_New(func);
        PyDict_SetItemString(pClassDic, def->ml_name, method);
        Py_DECREF(func);
        Py_DECREF(method);
    }

    // pClass = type(pClassName, pClassBases, pClassDic)
    PyObject *pClass = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, pClassName, pClassBases, pClassDic, NULL);

    Py_DECREF(pClassName);
    Py_DECREF(pClassBases);
    Py_DECREF(pClassDic);


    return pClass;
}

:

static PyMethodDef foo_Methods[] =
{
    { "__init__", fooInit, METH_VARARGS, "doc" },
    { "do_something", fooDoSomething, METH_VARARGS, "doc" },
    { 0, 0 },
};

PyObject * fooClass = createClassObject("fooClass", foo_Methods);
PyModule_AddObject(module, "foo", fooClass );

PyModule_AddObject , "foo" Python.

: "RomanK", PyTypeObject (, , ) .

: , PyTypeObject , PyModule_AddObject(), Python. , . , : https://docs.python.org/3.3/extending/newtypes.html?highlight=pytypeobject

+1

All Articles