IlmHamroh
Python kursi/Python va boshqa tillar6/16-dars18 daqiqa
Mundarija (22)

30.6-dars: C kengaytmasi yozish

30-QISM — PYTHON VA BOSHQA TILLAR · 6-dars


1. Kirish va motivatsiya

C API 30.5-bob bilan PyObject, havolalar hisobi va GIL ni ko'rdik. Endi ularni birlashtirib haqiqiy Python moduli yozamiz — C da yozilgan, lekin Python'dan import qilinadigan kengaytma (extension module). Bu numpy, lxml, pillow kabi mashhur kutubxonalar qanday qurilganini ochadi. C kengaytmasi ikki narsani talab qiladi: modul strukturasi (PyModuleDef — modul nomi, hujjat), funksiya jadvali (PyMethodDef — Python'ga ko'rinadigan funksiyalar ro'yxati). Yig'ilgach (setuptools bilan .so/.pyd fayl), oddiy Python moduli kabi ishlatiladi: import mening_modul. Bu Python tezligini C bilan kengaytirishning "asl" usuli — kuchli, lekin qiyin.

C kengaytmasi (extension module) — C da yozilgan, Python'ga import qilinadigan modul: modul strukturasi (PyModuleDef — nom, hujjat, funksiyalar), funksiya jadvali (PyMethodDef — Python funksiyalari ro'yxati), init funksiya (PyInit_<nom> — modul yaratish nuqtasi), yig'ish (setuptools — .so/.pyd kompilyatsiya). Foydalanish: tez modul (numpy), C kutubxona o'rash. Bu C API (30.5 — PyObject, havola) ustiga qurilgan. Bu 30.5 (C API), 30.7 (Cython — soddaroq) bilan bog'liq. Kengaytma — C modul (import). PyModuleDef + PyMethodDef.

Real vaziyat. lxml (XML kutubxona) nega tez? U C kengaytmasi: XML tahlili (parsing) libxml2 (C kutubxona) bilan, Python'ga esa import lxml (oddiy modul). C kengaytma libxml2 (tez C) ni Python'ga (qulay interfeys) bog'ladi: funksiya jadvali (PyMethodDef) Python funksiyalarini e'lon qildi, C ichida libxml2 chaqirildi. Foydalanuvchi C ni ko'rmaydi (faqat import lxml). C kengaytma — C tezlik + Python qulaylik (import).

Bu darsda C kengaytmasi yozishni o'rganamiz.

Bu darsda:

  • C kengaytmasi nima
  • PyMethodDef — funksiya jadvali
  • PyModuleDef — modul strukturasi
  • PyInit — init funksiya
  • Yig'ish (setuptools)
  • Kengaytma amaliyoti
  • Kengaytma vs muqobil
  • Amaliy: kengaytma modeli

ℹ C kengaytma C kompilyator talab qiladi; misollar kengaytma strukturasini (deterministik) modellashtiradi.


2. Nazariya — chuqur tushuntirish

2.1. C kengaytmasi nima

C da yozilgan Python moduli:

c
/* mening_modul.c — C kengaytmasi */
#include <Python.h>

/* Python funksiya (C da): qoshish(a, b) */
static PyObject *qoshish(PyObject *self, PyObject *args) {
    int a, b;
    PyArg_ParseTuple(args, "ii", &a, &b);   /* argumentlarni o'qish */
    return PyLong_FromLong(a + b);          /* natija (PyObject) */
}

C kengaytmasi (extension module) — C tilida yozilgan, Python'dan import qilinadigan modul: C API (30.5 — PyObject, havola) bilan Python funksiyalarini C da amalga oshiradi. Sabab: CPU-og'ir ish (bottleneck 29.2) C da tezroq (Python sikldan 100x); C kengaytma bu tezlikni Python'ga olib keladi (import — oddiy modul kabi). numpy, lxml, pillow — hammasi C kengaytmasi. Har C funksiya PyObject *self, PyObject *args oladi (Python argumentlari), PyObject * qaytaradi (natija). C kengaytma — C tezlik, Python interfeys. import qilinadi.

2.2. PyMethodDef — funksiya jadvali

Python'ga ko'rinadigan funksiyalar:

c
/* funksiya jadvali: Python'ga qaysi funksiyalar ko'rinadi */
static PyMethodDef Metodlar[] = {
    {"qoshish", qoshish, METH_VARARGS, "Ikki son yig'indisi"},
    {NULL, NULL, 0, NULL}   /* jadval oxiri (NULL bilan) */
};
/* {nom, C_funksiya, chaqiruv_turi, hujjat} */

PyMethodDef — C kengaytmadagi funksiya jadvali: Python'ga qaysi C funksiyalar ko'rinishini e'lon qiladi. Har satr: nom (Python'da ko'rinadigan — "qoshish"), C funksiya (haqiqiy C funksiya — qoshish), chaqiruv turi (METH_VARARGS — argumentlar tuple, METH_KEYWORDS — nomli), hujjat (docstring). Jadval {NULL, ...} bilan tugaydi (oxiri belgisi). Sabab: C kengaytmada ko'p funksiya bo'lishi mumkin; jadval Python'ga ro'yxat beradi (qaysi funksiya importda ko'rinadi). import modul; modul.qoshish(3, 5) — jadvaldan topadi. PyMethodDef — funksiya ro'yxati. Nom + C funksiya + tur + hujjat.

2.3. PyModuleDef — modul strukturasi

Modulning o'zi:

c
/* modul strukturasi: nom, hujjat, funksiya jadvali */
static struct PyModuleDef modul = {
    PyModuleDef_HEAD_INIT,
    "mening_modul",       /* modul nomi */
    "Modul hujjati",      /* modul docstring */
    -1,                   /* holat (global) */
    Metodlar              /* funksiya jadvali (PyMethodDef) */
};

PyModuleDef — C kengaytmaning modul strukturasi: modulning o'zini ta'riflaydi. Maydonlar: nom ("mening_modul" — importda ishlatiladigan), hujjat (modul docstring), holat (-1 — global, yoki modul bo'yicha), funksiya jadvali (Metodlar — PyMethodDef 2.2). Sabab: Python modulni bilishi kerak (nom, funksiyalar) — PyModuleDef bu ma'lumotni beradi (modul metama'lumoti). PyModuleDef_HEAD_INIT — standart boshlanish. Bu funksiya jadvalini (PyMethodDef) modul bilan bog'laydi. PyModuleDef — modul ta'rifi. Nom + hujjat + funksiya jadvali.

2.4. PyInit — init funksiya

Modul yaratish nuqtasi:

c
/* init funksiya: Python import qilganda chaqiriladi */
PyMODINIT_FUNC PyInit_mening_modul(void) {
    return PyModule_Create(&modul);   /* moduldan modul obyekti */
}
/* nom: PyInit_<modul_nomi> (Python topadi) */

PyInit — C kengaytmaning init funksiyasi: Python modulni import qilganda chaqiriladigan nuqta (kirish nuqtasi). Nomi PyInit_<modul_nomi> (PyInit_mening_modul) — Python shu nomni avtomatik topadi (import mexanizmi). U PyModule_Create(&modul) bilan modul obyektini yaratadi (PyModuleDef'dan) va qaytaradi. Sabab: importda Python modul obyektini yaratishi kerak; PyInit shu ishni qiladi (init — initialize). Nom qat'iy (PyInit_ + modul nomi) — Python topishi uchun. Bu modulning "tug'ilish" nuqtasi. PyInit — init funksiya (import nuqtasi). PyInit_. Modul yaratadi.

2.5. Yig'ish (setuptools)

C ni Python moduliga aylantirish:

python
# setup.py — C kengaytmasini yig'ish
from setuptools import setup, Extension

modul = Extension("mening_modul", sources=["mening_modul.c"])
setup(name="mening_modul", ext_modules=[modul])

# yig'ish: py setup.py build_ext --inplace
# natija: mening_modul.so (Linux) / .pyd (Windows)

Yig'ish (build) — C kodni Python moduliga (.so/.pyd) aylantirish: setuptools (Extension — C manba, setup — yig'ish) yoki zamonaviy meson/scikit-build. Sabab: C kodni Python import qila olmaydi — avval kompilyatsiya kerak (C → mashina kodi → .so/.pyd); setup.py build_ext shuni qiladi (C kompilyator chaqiradi). Natija: mening_modul.so (Linux) / .pyd (Windows) — Python import qiladigan fayl. Bu C kompilyator talab qiladi (gcc/msvc). Yig'ilgach: import mening_modul (oddiy modul kabi). Yig'ish — C → .so/.pyd. setuptools/meson. import qilinadi.

2.6. Kengaytma amaliyoti

C kengaytma amaliyotlari: funksiya jadvali (PyMethodDef — Python'ga funksiyalar, NULL bilan tugat); modul strukturasi (PyModuleDef — nom, jadval); init (PyInit_<nom> — qat'iy nom); argument o'qish (PyArg_ParseTuple — Python args → C); natija (PyLong_FromLong — C → PyObject); havola (INCREF/DECREF to'g'ri — 30.5); xato (NULL qaytar + istisno o'rnat); yig'ish (setup.py — C kompilyator). Tuzoqlar: havola xatosi (oqma/crash 30.5), NULL jadval oxiri unutish, PyInit nomi noto'g'ri (import topmaydi), argument turi ("ii" — format). C kengaytma kuchli, lekin qiyin (C API to'liq); ko'pincha Cython 30.7-bob yoki cffi 30.4-bob soddaroq. Amaliyot — jadval, init, havola, yig'ish. Kengaytma — C tezlik, qiyin.

2.7. Kengaytma vs muqobil

Usul Daraja Qiyinlik Tezlik
C kengaytma (C API) Past Yuqori Eng tez
cffi (30.4) O'rta O'rta Tez
Cython (30.7) O'rta Past Tez
ctypes (30.3) O'rta Past O'rta

Kengaytma vs muqobil: C kengaytma (C API — eng past daraja, eng qiyin, eng tez/moslashuvchan — to'liq nazorat); cffi (30.4 — o'rta, C deklaratsiya); Cython (30.7 — Python'ga o'xshash sintaksis, C ga kompilyatsiya — eng oson, tez); ctypes (30.3 — tayyor kutubxona chaqirish). Tanlov: maksimal nazorat/tezlik (C kengaytma — numpy yadrosi), oson tezlashtirish (Cython — ko'pchilik holat), mavjud C kutubxona (cffi/ctypes). Ko'pchilik dasturchi Cython dan boshlaydi (soddaroq, deyarli C tez); C kengaytma faqat kerak bo'lganda (chuqur nazorat). Kengaytma — kuchli, lekin oxirgi chora. Cython — amaliy boshlanish. Muqobil — kontekst.

2.8. Kengaytma — Python ni C bilan kengaytirish

C kengaytma asosiy g'oyasi — Python ni C bilan kengaytirish: C API (30.5 — PyObject, havola, GIL) ni birlashtirib, Python'ga import qilinadigan haqiqiy modul (.so/.pyd) yaratish. Bu Python "kengaytiriladigan til" ekanini ko'rsatadi (extensible — C bilan yangi imkoniyat qo'shish). numpy (massiv), lxml (XML), pillow (rasm) — hammasi C kengaytma (tez C yadro + Python interfeys). Struktura: funksiya jadvali (PyMethodDef — nima ko'rinadi), modul (PyModuleDef — modul ta'rifi), init (PyInit — yaratish). Yig'ilgach — oddiy modul (import). Bu 30.1 (to'g'ri til to'g'ri ishga — C yadro Python qobiq) ning eng past darajali amalga oshirilishi; amalda Cython 30.7-bob soddaroq. Kengaytma — Python + C (haqiqiy modul). Kengaytiriladigan til.


3. Tez ma'lumotnoma

c
/* C KENGAYTMASI (mening_modul.c) */
#include <Python.h>

/* 1. C FUNKSIYA (Python funksiya, C da) */
static PyObject *qoshish(PyObject *self, PyObject *args) {
    int a, b;
    PyArg_ParseTuple(args, "ii", &a, &b);   /* args → C */
    return PyLong_FromLong(a + b);          /* natija */
}

/* 2. FUNKSIYA JADVALI (PyMethodDef) */
static PyMethodDef Metodlar[] = {
    {"qoshish", qoshish, METH_VARARGS, "yig'indi"},
    {NULL, NULL, 0, NULL}   /* oxiri */
};

/* 3. MODUL STRUKTURASI (PyModuleDef) */
static struct PyModuleDef modul = {
    PyModuleDef_HEAD_INIT, "mening_modul", "hujjat", -1, Metodlar
};

/* 4. INIT (PyInit_<nom>) */
PyMODINIT_FUNC PyInit_mening_modul(void) {
    return PyModule_Create(&modul);
}
python
# YIG'ISH (setup.py)
from setuptools import setup, Extension
setup(ext_modules=[Extension("mening_modul", ["mening_modul.c"])])
# py setup.py build_ext --inplace → .so / .pyd
# import mening_modul; mening_modul.qoshish(3, 5)

Kengaytma xulosasi

C kengaytma — C da yozilgan Python moduli (import)
PyMethodDef — funksiya jadvali (nom, C funksiya, tur, hujjat)
PyModuleDef — modul strukturasi (nom, jadval)
PyInit_<nom> — init funksiya (import nuqtasi)
Yig'ish — setuptools → .so/.pyd · Cython 30.7-bob soddaroq

4. Batafsil misollar

C kengaytma C kompilyator talab qiladi; misollar kengaytma strukturasini (deterministik) modellashtiradi.

Misol 1 — Funksiya jadvali (PyMethodDef)

python
"""Funksiya jadvali: Python'ga ko'rinadigan funksiyalar (model)."""


def method_def(nom: str, hujjat: str, chaqiruv: str = "METH_VARARGS") -> dict:
    return {"nom": nom, "chaqiruv": chaqiruv, "hujjat": hujjat}


def main() -> None:
    jadval = [
        method_def("qoshish", "Ikki son yigindisi"),
        method_def("kopaytir", "Ikki son kopaytmasi"),
    ]

    print("=== 1. Funksiya jadvali ===")
    for m in jadval:
        print(f"  {m['nom']}: {m['hujjat']} ({m['chaqiruv']})")

    print("\n=== 2. Python'da ko'rinishi ===")
    print("  import modul")
    print("  modul.qoshish(3, 5)  # jadvaldan topadi")

    print("\n=== 3. Jadval oxiri ===")
    print("  {NULL, NULL, 0, NULL}  # oxir belgisi")

    print("\n=== 4. Struktura ===")
    print("  {nom, C_funksiya, chaqiruv_turi, hujjat}")
    print("  ⭐ PyMethodDef — funksiya jadvali (import)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Funksiya jadvali ===
  qoshish: Ikki son yigindisi (METH_VARARGS)
  kopaytir: Ikki son kopaytmasi (METH_VARARGS)

=== 2. Python'da ko'rinishi ===
  import modul
  modul.qoshish(3, 5)  # jadvaldan topadi

=== 3. Jadval oxiri ===
  {NULL, NULL, 0, NULL}  # oxir belgisi

=== 4. Struktura ===
  {nom, C_funksiya, chaqiruv_turi, hujjat}
  ⭐ PyMethodDef — funksiya jadvali (import)

Nima ko'rsatdi: 2.1, 2.2-bo'limlar.

Misol 2 — Modul strukturasi (PyModuleDef)

python
"""Modul strukturasi: nom, hujjat, funksiya jadvali (model)."""


def module_def(nom: str, hujjat: str, funksiyalar: list) -> dict:
    return {
        "nom": nom,
        "hujjat": hujjat,
        "holat": -1,            # global
        "funksiyalar": funksiyalar,
    }


def main() -> None:
    modul = module_def(
        "mening_modul",
        "Namuna kengaytma",
        ["qoshish", "kopaytir"],
    )

    print("=== 1. Modul nomi ===")
    print(f"  nom: {modul['nom']} (import shu nom)")

    print("\n=== 2. Modul hujjati ===")
    print(f"  hujjat: {modul['hujjat']}")

    print("\n=== 3. Funksiya jadvali (bog'liq) ===")
    print(f"  funksiyalar: {modul['funksiyalar']}")

    print("\n=== 4. Holat ===")
    print(f"  holat: {modul['holat']} (global)")
    print("  ⭐ PyModuleDef — modul ta'rifi (nom + jadval)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Modul nomi ===
  nom: mening_modul (import shu nom)

=== 2. Modul hujjati ===
  hujjat: Namuna kengaytma

=== 3. Funksiya jadvali (bog'liq) ===
  funksiyalar: ['qoshish', 'kopaytir']

=== 4. Holat ===
  holat: -1 (global)
  ⭐ PyModuleDef — modul ta'rifi (nom + jadval)

Nima ko'rsatdi: 2.3-bo'lim.

Misol 3 — Init funksiya (PyInit)

python
"""Init funksiya: PyInit_<nom>, import nuqtasi (model)."""


def pyinit_nomi(modul_nomi: str) -> str:
    return f"PyInit_{modul_nomi}"   # qat'iy naqsh


def import_jarayon(modul_nomi: str) -> list:
    return [
        f"import {modul_nomi}",
        f"Python {pyinit_nomi(modul_nomi)} ni qidiradi",
        "PyInit chaqiriladi (modul yaratiladi)",
        "modul obyekti qaytadi",
    ]


def main() -> None:
    print("=== 1. Init funksiya nomi ===")
    print(f"  modul: mening_modul")
    print(f"  init: {pyinit_nomi('mening_modul')}")

    print("\n=== 2. Nom naqshi ===")
    print("  PyInit_<modul_nomi> (Python topadi)")

    print("\n=== 3. Import jarayoni ===")
    for i, qadam in enumerate(import_jarayon("mening_modul"), 1):
        print(f"  {i}. {qadam}")

    print("\n=== 4. Natija ===")
    print("  PyModule_Create(&modul) — modul obyekti")
    print("  ⭐ PyInit — init funksiya (import nuqtasi)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Init funksiya nomi ===
  modul: mening_modul
  init: PyInit_mening_modul

=== 2. Nom naqshi ===
  PyInit_<modul_nomi> (Python topadi)

=== 3. Import jarayoni ===
  1. import mening_modul
  2. Python PyInit_mening_modul ni qidiradi
  3. PyInit chaqiriladi (modul yaratiladi)
  4. modul obyekti qaytadi

=== 4. Natija ===
  PyModule_Create(&modul) — modul obyekti
  ⭐ PyInit — init funksiya (import nuqtasi)

Nima ko'rsatdi: 2.4-bo'lim.

Misol 4 — Yig'ish oqimi (setuptools)

python
"""Yig'ish oqimi: C → .so/.pyd → import (model)."""


def yigish_oqim(manba: str, platforma: str) -> dict:
    kengaytma = ".pyd" if platforma == "windows" else ".so"
    natija = manba.replace(".c", kengaytma)
    return {"manba": manba, "platforma": platforma, "natija": natija}


def main() -> None:
    print("=== 1. C manba ===")
    print("  mening_modul.c (C kengaytma kodi)")

    print("\n=== 2. Yig'ish (Linux) ===")
    linux = yigish_oqim("mening_modul.c", "linux")
    print(f"  {linux['manba']} → {linux['natija']}")

    print("\n=== 3. Yig'ish (Windows) ===")
    win = yigish_oqim("mening_modul.c", "windows")
    print(f"  {win['manba']} → {win['natija']}")

    print("\n=== 4. Import ===")
    print("  py setup.py build_ext --inplace")
    print("  import mening_modul (oddiy modul kabi)")
    print("  ⭐ Yig'ish — C → .so/.pyd (kompilyatsiya)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. C manba ===
  mening_modul.c (C kengaytma kodi)

=== 2. Yig'ish (Linux) ===
  mening_modul.c → mening_modul.so

=== 3. Yig'ish (Windows) ===
  mening_modul.c → mening_modul.pyd

=== 4. Import ===
  py setup.py build_ext --inplace
  import mening_modul (oddiy modul kabi)
  ⭐ Yig'ish — C → .so/.pyd (kompilyatsiya)

Nima ko'rsatdi: 2.5-bo'lim.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"C kod to'g'ridan import" Avval yig'ish (.so/.pyd)
"Jadval oxiri kerak emas" {NULL,...} bilan tugaydi
"PyInit nomi ixtiyoriy" PyInit_ qat'iy
"Bir funksiya — jadvalsiz" PyMethodDef har doim
"Havola avtomatik" INCREF/DECREF qo'lda (30.5)
"C kengaytma oson" Qiyin (Cython soddaroq)
"Har doim C kengaytma" Ko'pincha Cython (30.7)
"Kompilyatorsiz ishlaydi" C kompilyator kerak

6. Keng tarqalgan xatolar va yechimlari

1. Jadval oxiri (NULL) unutish

c
static PyMethodDef M[] = {{"f", f, METH_VARARGS, ""}};  // NULL yo'q  // ⚠️
{..}, {NULL, NULL, 0, NULL}   // oxir belgisi                        // ✅

2. PyInit nomi noto'g'ri

c
PyMODINIT_FUNC init_modul(void)   // eski/noto'g'ri nom              // ⚠️
PyMODINIT_FUNC PyInit_mening_modul(void)   // PyInit_<nom>           // ✅

3. Argument format xatosi

c
PyArg_ParseTuple(args, "i", &a, &b);   // bitta i, ikkita arg        // ⚠️
PyArg_ParseTuple(args, "ii", &a, &b);   // "ii" (ikki int)            // ✅

4. Havola oqmasi (30.5)

c
PyObject *o = PyLong_FromLong(5);   // DECREF/qaytarish yo'q          // ⚠️
return PyLong_FromLong(a + b);   // qaytarilgan — havola o'tadi       // ✅

5. Yig'masdan import

python
import mening_modul   // .c yig'ilmagan (ImportError)                 // ⚠️
# py setup.py build_ext --inplace (avval yig')                        // ✅

6. C kompilyator yo'q

python
# setup.py build_ext (gcc/msvc yo'q — xato)                          // ⚠️
# C kompilyator o'rnat (yoki Cython/cffi)                             // ✅

7. Oddiy ishga C kengaytma

c
// oddiy funksiyaga to'liq C kengaytma (ortiqcha)                     // ⚠️
// Cython 30.7-bob — Python'ga o'xshash, soddaroq                       // ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 30.5-dars (o'tilgan): C API — PyObject, havola
  • 30.7-dars: Cython — soddaroq muqobil
  • 30.4-dars (o'tilgan): cffi — muqobil
  • 29.2-dars (o'tilgan): Bottleneck — C tezlik
  • 30.1-dars (o'tilgan): To'g'ri til to'g'ri ishga

8. Eng yaxshi amaliyotlar

  1. Funksiya jadvali NULL bilan tugat.

  2. PyInit_ qat'iy nom.

  3. Argument format to'g'ri (PyArg_ParseTuple).

  4. Havola to'g'ri (INCREF/DECREF — 30.5).

  5. Xato — NULL + istisno o'rnat.

  6. Yig'ish avtomatlashtir (setup.py).

  7. Ko'pincha Cython (soddaroq — 30.7).

  8. C kengaytma faqat maksimal nazorat kerak bo'lsa.


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # C kengaytmasi nima?
2.  # nega C kengaytma?
3.  # PyMethodDef nima?
4.  # jadval nima bilan tugaydi?
5.  # PyModuleDef nima?
6.  # PyInit nima?
7.  # PyInit nomi?
8.  # yig'ish nima beradi?
9.  # yig'ish vositasi?
10. # yig'ilgach qanday ishlatiladi?
11. # C kengaytma osonmi?
12. # soddaroq muqobil?
Javoblar
  1. C da yozilgan Python moduli (import)
  2. C tezlik + Python interfeys
  3. Funksiya jadvali (Python'ga ko'rinadigan)
  4. {NULL, NULL, 0, NULL}
  5. Modul strukturasi (nom, jadval)
  6. Init funksiya (import nuqtasi)
  7. PyInit_ (qat'iy)
  8. C → .so/.pyd (kompilyatsiya)
  9. setuptools (yoki meson)
  10. import modul (oddiy modul kabi)
  11. Yo'q (qiyin)
  12. Cython 30.7-bob yoki cffi (30.4)

Vazifa 2: Xatolarni tuzating

python
1.  # jadval NULL bilan tugamagan

2.  # init nomi init_modul

3.  # PyArg_ParseTuple "i" ikki argga

4.  # .c import qilingan (yig'ilmagan)

5.  # oddiy funksiyaga C kengaytma
Javoblar
python
1.  {NULL, NULL, 0, NULL} qo'sh

2.  PyInit_mening_modul (PyInit_<nom>)

3.  "ii" (ikki int)

4.  py setup.py build_ext (yig')

5.  Cython (soddaroq)

Vazifa 3: Funksiya jadvali

Modellang:

  1. Nom
  2. C funksiya
  3. Chaqiruv turi
  4. Oxir (NULL)

Vazifa 4: Modul strukturasi

Modellang:

  1. Nom
  2. Hujjat
  3. Jadval
  4. Holat

Vazifa 5: Init

Modellang:

  1. PyInit nomi
  2. Naqsh
  3. Import jarayoni
  4. Modul yaratish

Vazifa 6: Yig'ish

Modellang:

  1. C manba
  2. Kompilyatsiya
  3. .so/.pyd
  4. Import

Vazifa 7: O'ylash

C kengaytmasi Python'ni C bilan kengaytiradi (extensible) — Python "yopiq qora quti" emas, balki C darajasida ochiq. Nima uchun tilning "kengaytiriladigan" (extensible) bo'lishi uning ekotizimi (numpy, lxml, pillow) rivojlanishida hal qiluvchi, va nega "yopiq, kengaytirib bo'lmaydigan" til (garchi tez bo'lsa ham) ko'pincha yutqazadi?

Javob

Qisqa javob: "Kengaytiriladigan" bo'lish ekotizim rivojida hal qiluvchi, chunki: hech bir til hamma narsani o'zi qila olmaydi (Python sekin CPU-og'ir ishda — 29.2); kengaytiriladigan til (Python — C kengaytma) bu bo'shliqni jamoa to'ldirishiga imkon beradi (kim xohlasa C yadro yozadi — numpy, lxml, pillow), va shu tarzda til o'z chegarasidan oshadi (Python sekin, lekin numpy C yadro bilan tez). Bu tarmoq effekti (network effect) yaratadi: ko'proq kengaytma → ko'proq foydalanuvchi → ko'proq kengaytma (ijobiy sikl). "Yopiq, kengaytirib bo'lmaydigan til ko'pincha yutqazadi", chunki: (1) hamma ishga yaramaydi — bitta til hamma sohada (ilmiy hisoblash, veb, ML, tizim) eng yaxshi bo'la olmaydi; yopiq til o'z chegarasida qoladi (kengaytirib bo'lmaydi); (2) jamoa hissa qo'sha olmaydi — yopiq tilda faqat til yaratuvchilari qo'shadi (sekin, cheklangan); ochiq tilda butun jamoa (tez, keng — Python'da 400,000+ paket PyPI'da); (3) tarmoq effekti yo'q — kengaytma yo'q → foydalanuvchi kam → hissa kam (o'lik sikl); (4) maxsuslashuv yo'q — numpy (massiv), pandas (ma'lumot), torch (ML) — har biri C/C++ yadro + Python interfeys; yopiq til bularsiz umumiy qoladi. Python misolida: Python o'zi sekin (interpretatsiya — 30.1), lekin kengaytiriladigan (C API) → jamoa tez yadrolar yozdi (numpy, scipy, torch) → Python ilmiy hisoblash/ML'da hukmron bo'ldi (o'zi sekin bo'lsa ham!). Bu paradoks: sekin til, lekin tez ekotizim (kengaytma orqali). Aksincha, ba'zi tez tillar (kengaytirilmasa) tor doirada qoldi. Muhandislik saboqlari: kengaytiriladiganlik ekotizim uchun hal qiluvchi (til o'z chegarasidan oshadi); tarmoq effekti (kengaytma → foydalanuvchi → kengaytma); jamoa hissasi (ochiq — tez, yopiq — sekin); til tezligi emas, ekotizim g'olib (Python — sekin til, tez ekotizim); maxsuslashuv (yadro + interfeys — 30.1) kengaytma bilan.

1. Nega kengaytiriladiganlik hal qiluvchi

  • Hech bir til hamma narsani o'zi qila olmaydi (Python sekin CPU)
  • Jamoa bo'shliqni to'ldiradi (C yadro — numpy)
  • Til o'z chegarasidan oshadi (sekin til, tez yadro)
  • Tarmoq effekti (kengaytma → foydalanuvchi → kengaytma)

2. Nega yopiq til yutqazadi

  • Hamma ishga yaramaydi (o'z chegarasida qoladi)
  • Jamoa hissa qo'sha olmaydi (faqat yaratuvchilar)
  • Tarmoq effekti yo'q (o'lik sikl)
  • Maxsuslashuv yo'q (umumiy qoladi)

3. Python paradoksi

Jihat Python
Til o'zi Sekin (interpretatsiya)
Ekotizim Tez (C yadrolar)
Natija ML/ilmiy hukmron

Sekin til, tez ekotizim (kengaytma orqali).

4. Tarmoq effekti

Kengaytma → foydalanuvchi → kengaytma (ijobiy sikl). Yopiq: yo'q → kam → kam (o'lik sikl).

5. Muhandislik saboqlari

  1. Kengaytiriladiganlik — ekotizim hal qiluvchisi
  2. Tarmoq effekti (ijobiy sikl)
  3. Jamoa hissasi (ochiq tez, yopiq sekin)
  4. Ekotizim g'olib (til tezligi emas)
  5. Maxsuslashuv (yadro + interfeys)

6. Xulosa

  1. Kengaytiriladiganlik — til chegarasidan oshiradi
  2. Tarmoq effekti (kengaytma → foydalanuvchi)
  3. Python — sekin til, tez ekotizim (paradoks)
  4. Ekotizim g'olib (yopiq til yutqazadi)

Nimani mustahkamlaydi: 2.1, 2.8-bo'limlar.


Xulosa

Bu darsda C kengaytmasi yozishni o'rgandik.

Eng muhim uch fikr:

  1. C kengaytma va funksiya jadvali. C kengaytmasi (extension module) — C tilida yozilgan, Python'dan import qilinadigan modul: C API (30.5 — PyObject, havola) bilan Python funksiyalarini C da amalga oshiradi; CPU-og'ir ish (bottleneck 29.2) uchun C tezligini Python'ga olib keladi (numpy, lxml, pillow). PyMethodDef — funksiya jadvali: Python'ga qaysi C funksiyalar ko'rinishi (nom, C funksiya, chaqiruv turi METH_VARARGS, hujjat); jadval {NULL, ...} bilan tugaydi. import modul; modul.qoshish(3, 5) — jadvaldan topadi.

  2. Modul strukturasi, init, yig'ish. PyModuleDef — modul strukturasi: nom (importda), hujjat, holat, funksiya jadvali (bog'laydi). PyInit — init funksiya: importda chaqiriladigan nuqta, nomi qat'iy PyInit_<modul_nomi> (Python avtomatik topadi), PyModule_Create bilan modul obyektini yaratadi. Yig'ish (build) — C kodni .so/.pyd ga aylantirish (setuptools Extension/setup, yoki meson); C kompilyator kerak; py setup.py build_ext --inplace → yig'ilgach import (oddiy modul kabi).

  3. Muqobil va kengaytiriladigan til. Kengaytma vs muqobil: C kengaytma (C API — eng past daraja, eng qiyin, eng tez/moslashuvchan), cffi (30.4 — o'rta), Cython (30.7 — eng oson, Python'ga o'xshash sintaksis, deyarli C tez), ctypes 30.3-bob; ko'pchilik Cython dan boshlaydi (soddaroq), C kengaytma faqat maksimal nazorat kerak bo'lganda. C kengaytma — Python'ni C bilan kengaytirish (extensible til — yangi imkoniyat qo'shish); numpy, lxml, pillow shu bilan qurilgan (C yadro + Python interfeys). Kengaytiriladiganlik ekotizim rivojida hal qiluvchi (til o'z chegarasidan oshadi, tarmoq effekti, jamoa hissasi); Python paradoksi — sekin til, lekin tez ekotizim (kengaytma orqali ML/ilmiy hukmron).

Keyingi darsda Cython tushunchasini o'rganamiz: Python'ga o'xshash sintaksisda yozib, C ga kompilyatsiya qilinadigan til — statik turlar (cdef), tez sikllar va C kengaytmasiga soddaroq muqobil.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!