0Pricing
Python Academy · Lektion

Ein Python-C-Erweiterungsmodul schreiben

Erstellen Sie mit der Python/C-API eine einfache .so-Erweiterung.

Ein Python-C-Erweiterungsmodul schreiben ist eine kostenlose Python Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Python Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Python Academy-Kurs umfasst insgesamt 4 Lektionen.

Aufbau einer C-Erweiterung

Eine minimale C-Erweiterung enthält: Methodenfunktionen, eine Methodentabelle, eine Moduldefinitionsstruktur und einen PyInit_-Einstiegspunkt.

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

Argumente analysieren

PyArg_ParseTuple(args, "ii", &a, &b) analysiert Python-Argumente und schreibt sie in C-Variablen. Formatcodes: 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);
}

Rückgabewerte erstellen

Erstellen Sie Python-Rückgabewerte mit: 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
}

Referenzzählung

Jedes PyObject* besitzt einen Referenzzähler. Verwenden Sie Py_INCREF/Py_DECREF sorgfältig. Rückgabewerte von C-Funktionen übertragen dem Aufrufer den Besitz (gestohlene Referenzen).

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
}

Ausnahmen auslösen

Verwenden Sie PyErr_SetString(PyExc_ValueError, "msg"), um aus C eine Python-Ausnahme auszulösen, und geben Sie anschließend NULL zurück.

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 für C-Erweiterungen

Verwenden Sie setuptools.Extension, um die C-Quelldateien zu deklarieren. Erstellen Sie die Erweiterung mit 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)

Die erstellte Erweiterung verwenden

Importieren Sie die Erweiterung nach dem Erstellen wie jedes Python-Modul. Python findet sie, indem es nach myext.so (oder unter Windows nach .pyd) sucht.

# 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

Schlüsselwortargumente

Verwenden Sie PyArg_ParseTupleAndKeywords zusammen mit einer Schlüsselwortliste, um Schlüsselwortargumente in C-Funktionen zu unterstützen.

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

Konstanten auf Modulebene

Fügen Sie dem Modul in PyInit_ Integer- oder String-Konstanten mit PyModule_AddIntConstant hinzu.

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

Den GIL freigeben

Umschließen Sie reine C-Arbeit mit Py_BEGIN_ALLOW_THREADS / Py_END_ALLOW_THREADS, damit andere Python-Threads ausgeführt werden können, während der C-Code läuft.

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

Die Erweiterung testen

Testen Sie C-Erweiterungen über ihre Python-Schnittstelle mit pytest. Spezielle C-Testwerkzeuge sind nicht erforderlich.

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

Schnelltest

Was muss eine C-Erweiterungsfunktion zurückgeben, um zu signalisieren, dass eine Python-Ausnahme gesetzt wurde?

Zusammenfassung

Eine C-Erweiterung benötigt: Methodenfunktionen (Argumente analysieren, PyObject* zurückgeben), eine Methodentabelle, eine Moduldefinitionsstruktur und PyInit_name(). Lösen Sie Ausnahmen aus, indem Sie sie mit PyErr_SetString setzen und NULL zurückgeben. Geben Sie den GIL für reine C-Arbeit frei.

Häufig gestellte Fragen

Ist die Lektion „Ein Python-C-Erweiterungsmodul schreiben“ kostenlos?

Ja — der vollständige Text von „Ein Python-C-Erweiterungsmodul schreiben“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Python Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Python Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Ein Python-C-Erweiterungsmodul schreiben“?

Erstellen Sie mit der Python/C-API eine einfache .so-Erweiterung. Du übst Python Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Python Academy zu starten?

Keine Vorkenntnisse erforderlich. Python Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Ein Python-C-Erweiterungsmodul schreiben“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Python Academy-Lektion Code schreiben und ausführen?

Ja. Jede Python Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Warum C-Erweiterungen? Anwendungsfälle und Abwägungen
  2. ctypes: C-Bibliotheken aus Python aufrufen
  3. cffi: C Foreign Function Interface
  4. Ein Python-C-Erweiterungsmodul schreiben
← Zurück zu Python Academy