Python Academy · Pelajaran

Menulis Modul Sambungan C Python

Bina sambungan .so ringkas menggunakan API Python/C.

Pelajaran 4 daripada 413 langkah

Menulis Modul Sambungan C Python ialah pelajaran Python Academy percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Python Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Python Academy merangkumi sejumlah 4 pelajaran.

Anatomi Sambungan C

Sambungan C minimum mempunyai: fungsi kaedah, jadual kaedah, struktur takrif modul dan titik masuk 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);
}

Menghuraikan Argumen

PyArg_ParseTuple(args, "ii", &a, &b) menghuraikan argumen Python menjadi pemboleh ubah C. Kod 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);
}

Mengembalikan Nilai

Bina nilai pulangan Python dengan: 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
}

Pengiraan Rujukan

Setiap PyObject* mempunyai kiraan rujukan. Gunakan Py_INCREF/Py_DECREF dengan teliti. Nilai pulangan daripada fungsi C memberikan pemilikan kepada pemanggil (rujukan yang dipindahkan pemilikannya).

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
}

Mencetuskan Pengecualian

Gunakan PyErr_SetString(PyExc_ValueError, "msg") untuk mencetuskan pengecualian Python daripada C, kemudian kembalikan 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 untuk Sambungan C

Gunakan setuptools.Extension untuk mengisytiharkan fail sumber C. Bina dengan 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)

Menggunakan Sambungan yang Dibina

Selepas dibina, import sambungan tersebut seperti mana-mana modul Python. Python mencarinya dengan mencari myext.so (atau .pyd pada 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

Argumen Kata Kunci

Gunakan PyArg_ParseTupleAndKeywords dengan senarai kata kunci untuk menyokong argumen kata kunci dalam fungsi 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));
}

Pemalar Tahap Modul

Tambahkan pemalar integer atau rentetan kepada modul dalam PyInit_ menggunakan 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;
}

Melepaskan GIL

Bungkus kerja C tulen dengan Py_BEGIN_ALLOW_THREADS / Py_END_ALLOW_THREADS supaya bebenang Python lain boleh berjalan semasa kod C dilaksanakan.

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

Menguji Sambungan

Uji sambungan C melalui antara muka Python menggunakan pytest. Tiada alat ujian C khusus diperlukan.

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

Semakan Ringkas

Apakah yang mesti dikembalikan oleh fungsi sambungan C untuk menandakan bahawa pengecualian Python telah ditetapkan?

Ringkasan

Sambungan C memerlukan: fungsi kaedah (menghuraikan argumen, mengembalikan PyObject*), jadual kaedah, struktur takrif modul dan PyInit_name(). Cetuskan pengecualian dengan menetapkannya menggunakan PyErr_SetString dan mengembalikan NULL. Lepaskan GIL untuk kerja C tulen.

Percuma untuk bermula

Pelajari Python dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
76
Pelajaran
320

Soalan Lazim

Adakah pelajaran “Menulis Modul Sambungan C Python” percuma?

Ya — teks penuh “Menulis Modul Sambungan C Python” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Python Academy, tingkat taraf kepada CoddyKit PRO. Kursus Python Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Menulis Modul Sambungan C Python”?

Bina sambungan .so ringkas menggunakan API Python/C. Anda berlatih Python Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Python Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Python Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.

Berapa lamakah pelajaran “Menulis Modul Sambungan C Python” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Python Academy ini?

Ya. Setiap pelajaran Python Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Mengapa Sambungan C? Kegunaan dan Pertukaran
  2. ctypes: Memanggil Pustaka C daripada Python
  3. cffi: Antara Muka Fungsi Asing C
  4. Menulis Modul Sambungan C Python
← Kembali ke Python Academy