Écrire un module d’extension C pour Python
Créez une extension .so simple avec l’API Python/C.
Écrire un module d’extension C pour Python est une leçon Python Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Python Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Python Academy comprend 4 leçons au total.
Anatomie d’une extension C
Une extension C minimale comprend : des fonctions de méthode, une table des méthodes, une structure de définition du module et un point d’entrée PyInit_.
// 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);
}Analyser les arguments
PyArg_ParseTuple(args, "ii", &a, &b) analyse les arguments Python pour les placer dans des variables C. Codes de format : 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);
}Renvoyer des valeurs
Construisez les valeurs de retour Python avec : 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
}Comptage des références
Chaque PyObject* possède un compteur de références. Utilisez Py_INCREF/Py_DECREF avec précaution. Les valeurs renvoyées par les fonctions C transfèrent la propriété à l’appelant (références volées).
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
}Lever des exceptions
Utilisez PyErr_SetString(PyExc_ValueError, "msg") pour lever une exception Python depuis C, puis renvoyez 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 pour les extensions C
Utilisez setuptools.Extension pour déclarer les fichiers source C. Compilez avec 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)Utiliser l’extension compilée
Une fois compilée, importez l’extension comme n’importe quel module Python. Python la trouve en recherchant myext.so (ou .pyd sous 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) # ZeroDivisionErrorArguments nommés
Utilisez PyArg_ParseTupleAndKeywords avec une liste de mots-clés pour prendre en charge les arguments nommés dans les fonctions C.
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));
}Constantes au niveau du module
Ajoutez des constantes entières ou chaînes au module dans PyInit_ à l’aide de 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;
}Libérer le GIL
Entourez le travail effectué uniquement en C avec Py_BEGIN_ALLOW_THREADS / Py_END_ALLOW_THREADS afin de permettre l’exécution d’autres threads Python pendant l’exécution du code C.
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);
}Tester l’extension
Testez les extensions C via leur interface Python avec pytest. Aucun outil de test C particulier n’est nécessaire.
# 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)Vérification rapide
Que doit renvoyer une fonction d’extension C pour signaler qu’une exception Python a été définie ?
Récapitulatif
Une extension C nécessite : des fonctions de méthode (analyse des arguments, retour d’un PyObject*), une table des méthodes, une structure de définition du module et PyInit_name(). Levez les exceptions en les définissant avec PyErr_SetString, puis en renvoyant NULL. Libérez le GIL pour le travail effectué uniquement en C.
Questions Fréquemment Posées
La leçon « Écrire un module d’extension C pour Python » est-elle gratuite ?
Oui — le texte complet de « Écrire un module d’extension C pour Python » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Python Academy, passe à CoddyKit PRO. Le cours Python Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Écrire un module d’extension C pour Python » ?
Créez une extension .so simple avec l’API Python/C. Tu pratiques Python Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Python Academy ?
Aucune expérience préalable n'est requise. Python Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Écrire un module d’extension C pour Python » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Python Academy ?
Oui. Chaque leçon Python Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Pourquoi les extensions C ? Cas d’usage et compromis
- ctypes : appeler des bibliothèques C depuis Python
- cffi : interface de fonctions externes C
- Écrire un module d’extension C pour Python