Python Academy · Les

Een Python C-extensiemodule schrijven

Bouw een eenvoudige .so-extensie met de Python/C API.

Les 4 van 413 stappen

Een Python C-extensiemodule schrijven is een gratis Python Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Python Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Python Academy bevat in totaal 4 lessen.

Anatomie van C-extensies

Een minimale C-extensie bevat: methodefuncties, een methodetabel, een moduledefinitiestructuur en een PyInit_-ingangspunt.

// myext.c skeleton
#include <Python.h>

static PyObject* say_hello(PyObject* self, PyObject* args) {
    Py_RETURN_NONE;
}

static PyMethodDef methods[] = {
    {"say_hello", say_hello, METH_NOARGS, "Print hello"},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef module = {
    PyModuleDef_HEAD_INIT, "myext", NULL, -1, methods
};

PyMODINIT_FUNC PyInit_myext(void) {
    return PyModule_Create(&module);
}

Argumenten parseren

PyArg_ParseTuple(args, "ii", &a, &b) parseert Python-argumenten naar C-variabelen. Opmaakcodes: i=int, d=double, s=char*, O=PyObject*.

static PyObject* add(PyObject* self, PyObject* args) {
    int a, b;
    if (!PyArg_ParseTuple(args, "ii", &a, &b))
        return NULL;
    return PyLong_FromLong(a + b);
}

Waarden teruggeven

Maak Python-retourwaarden met: PyLong_FromLong, PyFloat_FromDouble, PyUnicode_FromString, Py_BuildValue.

// Return a Python tuple (int, float)
static PyObject* stats(PyObject* self, PyObject* args) {
    int n = 10;
    double avg = 5.0;
    return Py_BuildValue("(id)", n, avg);
    // Py_BuildValue format: i=int d=double s=str
}

Referentietelling

Elk PyObject* heeft een referentietelling. Gebruik Py_INCREF/Py_DECREF zorgvuldig. Retourwaarden van C-functies geven het eigenaarschap aan de aanroeper (gestolen referenties).

static PyObject* make_list(PyObject* self, PyObject* args) {
    PyObject* lst = PyList_New(3);
    for (int i = 0; i < 3; i++) {
        // PyList_SET_ITEM steals the reference:
        PyList_SET_ITEM(lst, i, PyLong_FromLong(i));
    }
    return lst;   // caller owns the list
}

Uitzonderingen opwerpen

Gebruik PyErr_SetString(PyExc_ValueError, "msg") om vanuit C een Python-uitzondering op te werpen en retourneer daarna NULL.

static PyObject* safe_div(PyObject* self, PyObject* args) {
    int a, b;
    if (!PyArg_ParseTuple(args, "ii", &a, &b)) return NULL;
    if (b == 0) {
        PyErr_SetString(PyExc_ZeroDivisionError, "division by zero");
        return NULL;
    }
    return PyLong_FromLong(a / b);
}

setup.py voor C-extensies

Gebruik setuptools.Extension om de C-bronbestanden te declareren. Bouw met python setup.py build_ext --inplace.

# setup.py
from setuptools import setup, Extension

setup(
    name="myext",
    ext_modules=[
        Extension(
            "myext",
            sources=["myext.c"],
            extra_compile_args=["-O2"],
        )
    ]
)
# python setup.py build_ext --inplace
# import myext; myext.add(3, 4)

De gebouwde extensie gebruiken

Importeer de extensie na het bouwen zoals elke Python-module. Python vindt deze door te zoeken naar myext.so of naar .pyd op Windows.

# After: python setup.py build_ext --inplace
import myext
print(myext.add(3, 4))        # 7
print(myext.safe_div(10, 2))  # 5
# myext.safe_div(1, 0)         # ZeroDivisionError

Trefwoordargumenten

Gebruik PyArg_ParseTupleAndKeywords met een trefwoordlijst om trefwoordargumenten in C-functies te ondersteunen.

static char* kwargs[] = {"x", "y", NULL};

static PyObject* hypot_c(PyObject* self,
                          PyObject* args,
                          PyObject* kw) {
    double x, y;
    if (!PyArg_ParseTupleAndKeywords(args, kw, "dd",
                                     kwargs, &x, &y))
        return NULL;
    return PyFloat_FromDouble(sqrt(x*x + y*y));
}

Constanten op moduleniveau

Voeg gehele getal- of stringconstanten aan de module toe in PyInit_ met PyModule_AddIntConstant.

PyMODINIT_FUNC PyInit_myext(void) {
    PyObject* m = PyModule_Create(&module);
    if (!m) return NULL;
    PyModule_AddIntConstant(m, "VERSION", 1);
    PyModule_AddStringConstant(m, "AUTHOR", "Alice");
    return m;
}

De GIL vrijgeven

Omring werk dat alleen uit C bestaat met Py_BEGIN_ALLOW_THREADS / Py_END_ALLOW_THREADS, zodat andere Python-threads kunnen worden uitgevoerd terwijl de C-code actief is.

static PyObject* heavy(PyObject* self, PyObject* args) {
    long n;
    if (!PyArg_ParseTuple(args, "l", &n)) return NULL;
    long result;
    Py_BEGIN_ALLOW_THREADS
        result = slow_c_computation(n);  // GIL released
    Py_END_ALLOW_THREADS
    return PyLong_FromLong(result);
}

De extensie testen

Test C-extensies via hun Python-interface met pytest. Er is geen speciaal C-testgereedschap nodig.

# test_myext.py
import pytest
import myext

def test_add(): assert myext.add(3, 4) == 7
def test_zero_div():
    with pytest.raises(ZeroDivisionError):
        myext.safe_div(1, 0)

Korte controle

Wat moet een C-extensiefunctie retourneren om aan te geven dat er een Python-uitzondering is ingesteld?

Samenvatting

Een C-extensie heeft het volgende nodig: methodefuncties die argumenten parseren en PyObject* retourneren, een methodetabel, een moduledef-structuur en PyInit_name(). Werp uitzonderingen op door ze in te stellen met PyErr_SetString en NULL te retourneren. Geef de GIL vrij voor werk dat alleen uit C bestaat.

Gratis beginnen

Leer Python met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
76
Lessen
320

Veelgestelde vragen

Is de les “Een Python C-extensiemodule schrijven” gratis?

Ja — de volledige tekst van “Een Python C-extensiemodule schrijven” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Python Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Python Academy bevat in totaal 4 lessen.

Wat leer ik in “Een Python C-extensiemodule schrijven”?

Bouw een eenvoudige .so-extensie met de Python/C API. Je oefent met Python Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Python Academy te beginnen?

Ervaring vooraf is niet nodig. Python Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “Een Python C-extensiemodule schrijven”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Python Academy?

Ja. Elke les over Python Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Waarom C-extensies? Toepassingen en afwegingen
  2. ctypes: C-bibliotheken aanroepen vanuit Python
  3. cffi: C Foreign Function Interface
  4. Een Python C-extensiemodule schrijven
← Terug naar Python Academy