IlmHamroh
Python kursi/Python va boshqa tillar5/16-dars19 daqiqa
Mundarija (22)

30.5-dars: CPython C API asoslari

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


1. Kirish va motivatsiya

ctypes 30.3-bob va cffi 30.4-bob tashqi C kutubxonalarini chaqiradi (Python tashqarisidagi C). Lekin boshqa yo'nalish ham bor: C kodidan Python interpretatori bilan ichkaridan ishlash — Python obyektlarini C darajasida yaratish, o'zgartirish, Python funksiyalarini C dan chaqirish. Bu CPython C API — CPython interpretatorining C interfeysi. U C kengaytmalari 30.6-bob ostida yotadi: numpy, lxml kabi tez kutubxonalar C API bilan yozilgan. C API ni tushunish — Python "sehri"ning ichini ko'rish: PyObject nima, havolalar hisobi (reference counting) qanday ishlaydi, GIL nima uchun kerak. Bu chuqur bilim — kam kishi biladi, lekin Python ichki mexanizmini tushunish uchun bebaho.

CPython C API — CPython interpretatori bilan C darajasida ishlash interfeysi: har narsa PyObject * (Python obyekti — C strukturasi), havolalar hisobi (reference counting — Py_INCREF/Py_DECREF, obyekt qachon o'chishi), API funksiyalar (PyLong_FromLong, PyList_New — obyekt yaratish), GIL (Global Interpreter Lock — bir vaqtda bir ip). Foydalanish: C kengaytma 30.6-bob, tez kutubxona (numpy). Bu ctypes/cffi (30.3-4 — tashqi C chaqirish) ning teskarisi (C dan Python ichiga). Bu 30.6 (kengaytma), GIL (17-qism) bilan bog'liq. C API — Python ichi C da. PyObject — har narsa obyekt.

Real vaziyat. numpy nega tez? Uning yadrosi C API bilan yozilgan: massiv amallari (qo'shish, ko'paytirish) C darajasida (Python sikldan 100x tez — 29.2 bottleneck). numpy PyObject bilan ishlaydi (Python massiv obyekti), lekin ichki hisoblar C da (havolalar hisobi, GIL boshqaruvi). C API numpy'ga Python bilan integratsiya (Python obyekti) va C tezlik (ichki amal) berdi. C API — Python qulaylik + C tezlik.

Bu darsda CPython C API asoslarini o'rganamiz.

Bu darsda:

  • CPython C API nima
  • PyObject — har narsa obyekt
  • Havolalar hisobi (reference counting)
  • API funksiyalari (obyekt yaratish)
  • GIL (Global Interpreter Lock)
  • C API amaliyoti
  • C API tuzoqlari
  • Amaliy: C API modeli

ℹ C API C kompilyator/CPython ichini talab qiladi; misollar C API mantiqini (deterministik) modellashtiradi.


2. Nazariya — chuqur tushuntirish

2.1. CPython C API nima

Python ichi C da:

c
/* C kodida Python obyekti bilan ishlash */
#include <Python.h>

PyObject *son = PyLong_FromLong(42);   /* Python int (C dan) */
long qiymat = PyLong_AsLong(son);      /* C long (Python dan) */
Py_DECREF(son);                        /* havolani kamaytirish */

CPython C API — CPython interpretatori bilan C darajasida ishlash interfeysi: C kodidan Python obyektlarini yaratish (PyLong_FromLong — int), o'zgartirish, Python funksiyalarini chaqirish. Sabab: ctypes/cffi (30.3-4) tashqi C ni chaqiradi (Python → C), C API teskari (C → Python ichiga) — C kengaytma 30.6-bob, tez kutubxona (numpy, lxml) shu bilan yoziladi. Bu CPython'ga xos (Python implementatsiyasi — 30.7 PyPy boshqacha). C API Python ichki mexanizmini ochadi (PyObject, havola, GIL). C API — Python ichi C da. CPython interfeysi. Kengaytma asosi.

2.2. PyObject — har narsa obyekt

Python'da hamma narsa PyObject:

c
/* Python'da har narsa PyObject * (C strukturasi) */
PyObject *son = ...;    /* int ham PyObject */
PyObject *satr = ...;   /* str ham PyObject */
PyObject *royxat = ...; /* list ham PyObject */

/* har PyObject: tur (type) + havolalar soni (refcount) */

PyObject — CPython'da har Python obyektinin C ko'rinishi (C strukturasi): int, str, list, funksiya — hammasi PyObject * (pointer). Har PyObjectda: tur (ob_type — int/str/... — obyekt qandayligini biladi), havolalar soni (ob_refcnt — nechta havola — 2.3). Sabab: Python "hamma narsa obyekt" (16-qism) — C darajasida bu PyObject (yagona struktura, tur bilan farqlanadi); API funksiyalar PyObject * bilan ishlaydi (universal). Bu Python'ning dinamik tabiati (tur ish vaqtida — ob_type). PyObject — har Python obyekti (C da). Tur + havola soni. Universal struktura.

2.3. Havolalar hisobi (reference counting)

Obyekt qachon o'chadi:

c
PyObject *obj = PyLong_FromLong(42);  /* refcount = 1 */
Py_INCREF(obj);                        /* refcount = 2 (havola qo'shildi) */
Py_DECREF(obj);                        /* refcount = 1 */
Py_DECREF(obj);                        /* refcount = 0 → obyekt o'chadi */

Havolalar hisobi (reference counting) — CPython'ning xotirani boshqarish usuli: har PyObjectda havolalar soni (ob_refcnt — nechta joyda ishlatilyapti); Py_INCREF (havola qo'shildi — +1), Py_DECREF (havola ketdi — -1); 0 ga tushsa — obyekt o'chadi (xotira bo'shatiladi). Sabab: C da xotirani qo'lda boshqarish kerak (Python avtomatik — 21-qism GC); C API'da dasturchi qo'lda INCREF/DECREF qiladi (havolani to'g'ri hisoblash). Xato: DECREF unutish (xotira oqadi — memory leak), ortiqcha DECREF (obyekt erta o'chadi — crash). Bu C API'ning eng qiyin qismi (havolani to'g'ri). Havola hisobi — xotira boshqaruvi. INCREF/DECREF — qo'lda. 0 — o'chadi.

2.4. API funksiyalari (obyekt yaratish)

Python obyektlarini C dan:

c
/* obyekt yaratish (turdan) */
PyObject *son = PyLong_FromLong(42);          /* int */
PyObject *matn = PyUnicode_FromString("salom"); /* str */
PyObject *royxat = PyList_New(0);              /* bo'sh list */

/* obyektdan qiymat olish */
long q = PyLong_AsLong(son);                    /* int → C long */

API funksiyalar — C API Python obyektlarini yaratish/o'zgartirish uchun ko'p funksiya beradi: yaratish (PyLong_FromLong — int, PyUnicode_FromString — str, PyList_New — list, PyDict_New — dict), o'qish (PyLong_AsLong — int → C long), amal (PyList_Append — qo'shish, PyDict_SetItem — o'rnatish). Sabab: C da Python obyektini to'g'ridan yaratib bo'lmaydi (C API kerak — interpretator ichi); funksiyalar Py<Tur>_<Amal> naqshida (PyLong, PyUnicode, PyList). Har biri PyObject * qaytaradi (yoki oladi). Bu C kengaytmaning asosiy ishi (Python obyekti bilan). API funksiya — obyekt yaratish/amal. Py_ — naqsh.

2.5. GIL (Global Interpreter Lock)

Bir vaqtda bir ip:

GIL — Global Interpreter Lock
   CPython'da bir vaqtda faqat BIR ip Python kodini bajaradi
   (havolalar hisobi xavfsizligi uchun)

C API'da: GIL ni bo'shatish mumkin (uzoq C amal — parallel)
   Py_BEGIN_ALLOW_THREADS ... Py_END_ALLOW_THREADS

GIL (Global Interpreter Lock) — CPython'ning global qulfi: bir vaqtda faqat bir ip Python kodini (va C API'ni) bajaradi. Sabab: havolalar hisobi (2.3 — ob_refcnt) ip-xavfsiz emas (ikki ip bir vaqtda INCREF/DECREF — poyga, buzilish); GIL buni oldini oladi (bir ip — xavfsiz). Kamchilik: ko'p yadroli CPU'da Python parallel emas (bir ip — 17-qism); shuning uchun CPU-og'ir ish multiprocessing (jarayonlar). C API'da: uzoq C amal (Python obyekti tegmaydi) uchun GIL ni bo'shatish mumkin (Py_BEGIN_ALLOW_THREADS — parallel C, numpy shunday). GIL — bir ip qulfi. Havola xavfsizligi. C API bo'shatishi mumkin.

2.6. C API amaliyoti

C API amaliyotlari: havolani to'g'ri (INCREF/DECREF muvozanat — eng muhim, oqma/crash 2.3); xato tekshirish (API NULL qaytarsa — xato, tekshir); GIL (uzoq C amal — bo'shat, parallel); tur tekshirish (PyLong_Check — turni tasdiqla); C kengaytma (30.6 — C API bilan modul); soddaroq muqobil (cffi/Cython 30.4/30.7 — C API qiyin, ko'pincha kerak emas). Tuzoqlar: havola xatosi (oqma/crash — eng ko'p), NULL tekshirmaslik (crash), GIL (noto'g'ri bo'shatish — poyga). C API qiyin, xatoga moyil — faqat kerak bo'lsa (numpy darajasida). Ko'p holatda Cython 30.7-bob soddaroq. Amaliyot — havola to'g'ri, ehtiyot. C API — qiyin, kuchli.

2.7. C API tuzoqlari

C API asosiy tuzoqlari: havola oqmasi (DECREF unutish — xotira to'ladi), ortiqcha DECREF (obyekt erta o'chadi — crash, eng xavfli), NULL tekshirmaslik (API xato → NULL → foydalanish → crash), GIL xatosi (bo'shatib Python obyektga tegish — poyga/crash), tur xatosi (PyLong_AsLong str'da — xato), versiya (C API Python versiyaga bog'liq — 3.11/3.12 farqi), murakkablik (C API katta, ko'p funksiya — o'rganish qiyin). Sabab: C API past daraja (xotira/havola qo'lda — Python avtomatiklik yo'q). Yechim: ehtiyot (havola/NULL), yoki soddaroq vosita (Cython 30.7 — C API ni yashiradi). Ko'pincha C API to'g'ridan kerak emas. Tuzoq — havola, NULL, GIL. Ehtiyot yoki Cython.

2.8. C API — Python ning C darajasi

C API asosiy g'oyasi — Python'ning C darajasi: CPython interpretatori C da yozilgan (Python obyektlari PyObject, havolalar hisobi, GIL — hammasi C mexanizmi); C API bu darajani C dasturchiga ochadi (Python obyekti yaratish, o'zgartirish C dan). Bu ctypes/cffi (30.3-4 — tashqi C) ning teskarisi (C dan Python ichiga), va C kengaytma (30.6 — numpy, lxml) ning asosi. C API Python "sehri"ni ochadi: obyekt nima (PyObject), qachon o'chadi (havola hisobi), nega bir ip (GIL). Bu chuqur bilim (kam kishi biladi), lekin Python ichki mexanizmini tushunish uchun bebaho; amalda ko'pincha Cython 30.7-bob yoki cffi 30.4-bob soddaroq. C API — Python ichi, C daraja. PyObject/havola/GIL — mexanizm.


3. Tez ma'lumotnoma

c
/* CPYTHON C API (C kodida) */
#include <Python.h>

/* PYOBJECT — har narsa obyekt */
PyObject *obj;   /* int, str, list — hammasi PyObject * */
/* har obj: ob_type (tur) + ob_refcnt (havolalar soni) */

/* HAVOLALAR HISOBI (reference counting) */
Py_INCREF(obj);   /* +1 (havola qo'shildi) */
Py_DECREF(obj);   /* -1 (0 ga tushsa → o'chadi) */

/* OBYEKT YARATISH (API funksiyalari) */
PyObject *son = PyLong_FromLong(42);            /* int */
PyObject *matn = PyUnicode_FromString("salom"); /* str */
PyObject *royxat = PyList_New(0);               /* list */
long q = PyLong_AsLong(son);                     /* int → C long */

/* GIL (Global Interpreter Lock) */
Py_BEGIN_ALLOW_THREADS   /* GIL bo'shat (uzoq C amal) */
/* ... C hisoblari (Python obyekt tegmaydi) ... */
Py_END_ALLOW_THREADS     /* GIL qaytar */

C API xulosasi

CPython C API — Python ichi C darajada (ctypes teskarisi)
PyObject — har narsa obyekt (tur + havolalar soni)
Havola hisobi — INCREF/DECREF (0 → o'chadi), qo'lda
GIL — bir vaqtda bir ip (havola xavfsizligi)
Qiyin, xatoga moyil — ko'pincha Cython/cffi soddaroq

4. Batafsil misollar

C API C kompilyator/CPython ichini talab qiladi; misollar C API mantiqini (deterministik) modellashtiradi.

Misol 1 — PyObject (tur + havola)

python
"""PyObject: har obyekt tur + havolalar soni (C API modeli)."""


class PyObjectModel:
    def __init__(self, tur: str, qiymat) -> None:
        self.ob_type = tur       # tur (int/str/list)
        self.qiymat = qiymat
        self.ob_refcnt = 1       # havolalar soni (yaratilganda 1)


def main() -> None:
    print("=== 1. int obyekti ===")
    son = PyObjectModel("int", 42)
    print(f"  tur: {son.ob_type}, qiymat: {son.qiymat}")
    print(f"  havolalar: {son.ob_refcnt}")

    print("\n=== 2. str obyekti ===")
    matn = PyObjectModel("str", "salom")
    print(f"  tur: {matn.ob_type}, qiymat: {matn.qiymat}")

    print("\n=== 3. list obyekti ===")
    royxat = PyObjectModel("list", [])
    print(f"  tur: {royxat.ob_type}")

    print("\n=== 4. Umumiy ===")
    print("  hammasi PyObject (tur + havolalar soni)")
    print("  ⭐ PyObject — har narsa obyekt (C da)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. int obyekti ===
  tur: int, qiymat: 42
  havolalar: 1

=== 2. str obyekti ===
  tur: str, qiymat: salom

=== 3. list obyekti ===
  tur: list

=== 4. Umumiy ===
  hammasi PyObject (tur + havolalar soni)
  ⭐ PyObject — har narsa obyekt (C da)

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

Misol 2 — Havolalar hisobi (INCREF/DECREF)

python
"""Havola hisobi: INCREF/DECREF, 0 ga tushsa o'chadi (C API modeli)."""


class RefCounted:
    def __init__(self) -> None:
        self.refcnt = 1
        self.tirik = True

    def incref(self) -> None:
        self.refcnt += 1

    def decref(self) -> None:
        self.refcnt -= 1
        if self.refcnt == 0:
            self.tirik = False   # obyekt o'chadi


def main() -> None:
    print("=== 1. Yaratish (refcount = 1) ===")
    obj = RefCounted()
    print(f"  havolalar: {obj.refcnt}, tirik: {obj.tirik}")

    print("\n=== 2. INCREF (havola qo'shildi) ===")
    obj.incref()
    print(f"  havolalar: {obj.refcnt}")

    print("\n=== 3. DECREF (havola ketdi) ===")
    obj.decref()
    print(f"  havolalar: {obj.refcnt}, tirik: {obj.tirik}")

    print("\n=== 4. DECREF (0 → o'chadi) ===")
    obj.decref()
    print(f"  havolalar: {obj.refcnt}, tirik: {obj.tirik}")
    print("  ⭐ Havola 0 → obyekt o'chadi (xotira bo'shaydi)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Yaratish (refcount = 1) ===
  havolalar: 1, tirik: True

=== 2. INCREF (havola qo'shildi) ===
  havolalar: 2

=== 3. DECREF (havola ketdi) ===
  havolalar: 1, tirik: True

=== 4. DECREF (0 → o'chadi) ===
  havolalar: 0, tirik: False
  ⭐ Havola 0 → obyekt o'chadi (xotira bo'shaydi)

Nima ko'rsatdi: 2.3-bo'lim.

Misol 3 — API funksiyalari (obyekt yaratish)

python
"""API funksiyalari: Py<Tur>_<Amal> naqshi (C API modeli)."""


def py_long_from_long(qiymat: int) -> dict:
    return {"tur": "int", "qiymat": qiymat, "refcnt": 1}


def py_unicode_from_string(matn: str) -> dict:
    return {"tur": "str", "qiymat": matn, "refcnt": 1}


def py_list_new() -> dict:
    return {"tur": "list", "qiymat": [], "refcnt": 1}


def main() -> None:
    print("=== 1. PyLong_FromLong (int) ===")
    son = py_long_from_long(42)
    print(f"  {son['tur']}: {son['qiymat']} (refcnt {son['refcnt']})")

    print("\n=== 2. PyUnicode_FromString (str) ===")
    matn = py_unicode_from_string("salom")
    print(f"  {matn['tur']}: {matn['qiymat']}")

    print("\n=== 3. PyList_New (list) ===")
    royxat = py_list_new()
    print(f"  {royxat['tur']}: {royxat['qiymat']}")

    print("\n=== 4. Naqsh ===")
    print("  Py<Tur>_<Amal>: PyLong, PyUnicode, PyList")
    print("  har biri PyObject qaytaradi (refcount 1)")
    print("  ⭐ API funksiya — obyekt yaratish (C dan)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. PyLong_FromLong (int) ===
  int: 42 (refcnt 1)

=== 2. PyUnicode_FromString (str) ===
  str: salom

=== 3. PyList_New (list) ===
  list: []

=== 4. Naqsh ===
  Py<Tur>_<Amal>: PyLong, PyUnicode, PyList
  har biri PyObject qaytaradi (refcount 1)
  ⭐ API funksiya — obyekt yaratish (C dan)

Nima ko'rsatdi: 2.4-bo'lim.

Misol 4 — GIL (bir ip)

python
"""GIL: bir vaqtda bir ip, uzoq C amalda bo'shatish mumkin (model)."""


class GILModel:
    def __init__(self) -> None:
        self.egasi = None   # GIL kimda

    def olish(self, ip: str) -> bool:
        if self.egasi is None:
            self.egasi = ip
            return True
        return False   # band (boshqa ip)

    def boshatish(self) -> None:
        self.egasi = None


def main() -> None:
    gil = GILModel()

    print("=== 1. Ip A GIL oladi ===")
    ok = gil.olish("A")
    print(f"  A oldi: {ok}, egasi: {gil.egasi}")

    print("\n=== 2. Ip B kutadi (GIL band) ===")
    ok = gil.olish("B")
    print(f"  B oldi: {ok} (A ushlab turibdi)")

    print("\n=== 3. A GIL ni bo'shatadi (uzoq C amal) ===")
    gil.boshatish()
    print(f"  egasi: {gil.egasi}")

    print("\n=== 4. B endi oladi ===")
    ok = gil.olish("B")
    print(f"  B oldi: {ok}, egasi: {gil.egasi}")
    print("  ⭐ GIL — bir vaqtda bir ip (bo'shatish mumkin)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Ip A GIL oladi ===
  A oldi: True, egasi: A

=== 2. Ip B kutadi (GIL band) ===
  B oldi: False (A ushlab turibdi)

=== 3. A GIL ni bo'shatadi (uzoq C amal) ===
  egasi: None

=== 4. B endi oladi ===
  B oldi: True, egasi: B
  ⭐ GIL — bir vaqtda bir ip (bo'shatish mumkin)

Nima ko'rsatdi: 2.5-bo'lim.


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

Noto'g'ri fikr To'g'risi
"C API = ctypes" C API teskari (C dan Python ichiga)
"int obyekt emas" int ham PyObject (C da)
"Xotira avtomatik" C API'da havola qo'lda (INCREF/DECREF)
"DECREF unutsa mayli" Xotira oqadi (memory leak)
"GIL keraksiz" Havola xavfsizligi (bir ip)
"GIL doim ushlanadi" Uzoq C amalda bo'shatiladi
"C API oson" Qiyin, xatoga moyil
"Har doim C API" Ko'pincha Cython/cffi soddaroq

6. Keng tarqalgan xatolar va yechimlari

1. DECREF unutish (oqma)

c
PyObject *o = PyLong_FromLong(5);   // DECREF yo'q          // ⚠️
PyObject *o = PyLong_FromLong(5); ...; Py_DECREF(o);         // ✅

2. Ortiqcha DECREF (crash)

c
Py_DECREF(o); Py_DECREF(o);   // ikki marta (crash)          // ⚠️
// havolani to'g'ri hisobla (bir marta)                       // ✅

3. NULL tekshirmaslik

c
PyObject *o = PyList_GetItem(...); o->...   // NULL bo'lsa crash  // ⚠️
if (o == NULL) { /* xato */ }                                 // ✅

4. GIL bo'shatib Python obyektga tegish

c
Py_BEGIN_ALLOW_THREADS PyList_Append(...)   // poyga          // ⚠️
// GIL bo'shatilganda faqat C (Python obyekt tegma)            // ✅

5. Tur tekshirmaslik

c
PyLong_AsLong(str_obj)   // str'da int amal (xato)            // ⚠️
if (PyLong_Check(o)) { PyLong_AsLong(o); }                    // ✅

6. C API oddiy ishga

c
// oddiy funksiyaga to'liq C API (ortiqcha, qiyin)            // ⚠️
// Cython 30.7-bob yoki cffi 30.4-bob soddaroq                     // ✅

7. Versiya farqini e'tiborsiz

c
// 3.11 C API 3.12'da o'zgargan (moslik)                      // ⚠️
// versiyaga mos C API (stable ABI)                            // ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 30.6-dars: C kengaytmasi — C API bilan modul
  • 30.4-dars (o'tilgan): cffi — soddaroq muqobil
  • 30.7-dars: Cython — C API ni yashiradi
  • 17-qism (o'tilgan): GIL va iplar
  • 21-qism (o'tilgan): Xotira va GC

8. Eng yaxshi amaliyotlar

  1. Havolani to'g'ri (INCREF/DECREF muvozanat).

  2. NULL tekshirish (API xatosi).

  3. Tur tekshirish (PyLong_Check).

  4. GIL (uzoq C amalda bo'shat, ehtiyot).

  5. Versiyaga mos (stable ABI).

  6. Soddaroq muqobil (Cython/cffi — ko'pincha).

  7. C API faqat kerak bo'lsa (numpy darajasi).

  8. Xotira oqmasini tekshir (havola audit).


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # CPython C API nima?
2.  # ctypes farqi?
3.  # PyObject nima?
4.  # har PyObject nimaga ega?
5.  # havolalar hisobi nima?
6.  # INCREF nima?
7.  # DECREF 0 da?
8.  # API funksiya naqshi?
9.  # GIL nima?
10. # nega GIL?
11. # GIL bo'shatish?
12. # C API oddiymi?
Javoblar
  1. Python ichi bilan C darajada ishlash
  2. C API teskari (C dan Python ichiga)
  3. Har Python obyektining C ko'rinishi
  4. Tur (ob_type) + havolalar soni (refcnt)
  5. Obyektga nechta havola (xotira boshqaruvi)
  6. Havola qo'shildi (+1)
  7. Obyekt o'chadi (xotira bo'shaydi)
  8. Py_ (PyLong_FromLong)
  9. Global qulf (bir vaqtda bir ip)
  10. Havola hisobi xavfsizligi
  11. Uzoq C amalda (parallel)
  12. Yo'q (qiyin, xatoga moyil)

Vazifa 2: Xatolarni tuzating

python
1.  # PyLong_FromLong, DECREF yo'q

2.  # DECREF ikki marta

3.  # NULL tekshirmasdan foydalanish

4.  # GIL bo'shatib PyList_Append

5.  # oddiy funksiyaga to'liq C API
Javoblar
python
1.  Py_DECREF (havolani kamaytir)

2.  bir marta DECREF (havola to'g'ri)

3.  if (o == NULL) tekshir

4.  GIL bo'shatilganda faqat C

5.  Cython/cffi (soddaroq)

Vazifa 3: PyObject

Modellang:

  1. Tur
  2. Havola soni
  3. int/str/list
  4. Universal

Vazifa 4: Havola

Modellang:

  1. INCREF
  2. DECREF
  3. 0 → o'chadi
  4. Oqma

Vazifa 5: API funksiya

Modellang:

  1. Yaratish
  2. O'qish
  3. Naqsh
  4. PyObject

Vazifa 6: GIL

Modellang:

  1. Bir ip
  2. Band
  3. Bo'shatish
  4. Parallel C

Vazifa 7: O'ylash

CPython C API'da xotira qo'lda boshqariladi (havola hisobi — INCREF/DECREF), Python'da esa avtomatik (GC). Nima uchun "avtomatik xotira boshqaruvi" (GC) qulaylik uchun to'lov sifatida "nazorat va tezlik"dan voz kechadi, va nega C API kabi past daraja "qo'lda nazorat" beradi-yu, lekin "xato yukini" dasturchiga yuklaydi?

Javob

Qisqa javob: Bu abstraksiya darajasi savdosi (17.x, 27.x — abstraksiya): yuqori daraja (Python GC) qulaylik beradi (dasturchi xotira haqida o'ylamaydi), lekin nazorat va tezlikdan voz kechadi (GC qachon ishlashini nazorat qilmaysiz, u vaqt/xotira sarflaydi); past daraja (C API — qo'lda havola) nazorat va tezlik beradi (aniq qachon o'chadi, qo'shimcha yuk yo'q), lekin xato yukini dasturchiga yuklaydi (havolani noto'g'ri hisoblasang — oqma yoki crash). "Avtomatik xotira boshqaruvi qulaylik uchun nazorat/tezlikdan voz kechadi", chunki: (1) qulaylik — Python dasturchi x = [1,2,3] yozadi, xotira haqida o'ylamaydi (GC ajratadi/bo'shatadi — 21-qism); (2) nazorat yo'qoladi — GC qachon ishlashini nazorat qilmaysiz (kutilmagan pauza — real-time tizimda muammo), qaysi obyekt qachon o'chishini aniq bilmaysiz; (3) tezlik to'lovi — GC ishlashi vaqt sarflaydi (havolalarni kuzatish, sikllar — 21-qism), qo'shimcha xotira (refcount maydoni har obyektda). "C API past daraja qo'lda nazorat beradi-yu, xato yukini yuklaydi", chunki: (1) nazorat — aniq qachon o'chishini belgilaysiz (DECREF → darhol bo'shaydi, pauza yo'q), tezlik (qo'shimcha GC yo'q); (2) xato yuki — havolani to'g'ri hisoblash dasturchi zimmasida (INCREF/DECREF muvozanat); bir xato — oqma (DECREF unutish) yoki crash (ortiqcha DECREF); (3) kognitiv yuk — har obyekt havolasini kuzatish (charchatuvchi, xatoga moyil). Bu umumiy muhandislik tamoyili: abstraksiya qulaylik beradi, lekin nazorat/tezlikni yashiradi (17.x — abstraksiya narxi); past daraja nazorat/tezlik beradi, lekin murakkablik/xato yukini oshiradi. Tanlov kontekstga bog'liq: ko'pchilik ilova (Python GC — qulaylik ustun, tezlik yetarli), kam holat (C API/qo'lda — tezlik/nazorat kritik, numpy yadrosi). Shuning uchun numpy: yadrosi C API (tezlik/nazorat), lekin Python interfeysi (qulaylik) — ikki dunyoning yaxshisi (30.1 — to'g'ri til to'g'ri ishga). Muhandislik saboqlari: abstraksiya qulaylik ↔ nazorat/tezlik savdosi; avtomatik (GC) — qulaylik, xatosizlik, lekin sekinroq/nazoratsiz; qo'lda (C API) — tezlik/nazorat, lekin xato yuki; kontekst tanlaydi (ilova → GC, yadro → qo'lda); eng yaxshisi ko'pincha qatlam (numpy — C yadro + Python interfeys).

1. Nega avtomatik nazorat/tezlikdan voz kechadi

  • Qulaylik: xotira haqida o'ylamaysiz
  • Nazorat yo'qoladi: GC qachon (pauza), qaysi obyekt qachon
  • Tezlik to'lovi: GC ishlashi + qo'shimcha xotira

2. Nega C API nazorat berib, xato yuklaydi

  • Nazorat: aniq qachon o'chadi (pauza yo'q, tez)
  • Xato yuki: havola to'g'ri hisoblash dasturchi zimmasida
  • Kognitiv yuk: har havola kuzatish (charchatuvchi)

3. Abstraksiya savdosi

Daraja Beradi Oladi
Yuqori (GC) Qulaylik, xatosizlik Nazorat, tezlik
Past (C API) Nazorat, tezlik Xato yuki, murakkablik

4. Kontekst tanlaydi

Ilova (ko'pchilik) → GC (qulaylik ustun). Yadro (kam) → qo'lda (tezlik kritik).

5. Eng yaxshi — qatlam

numpy: C yadro (tezlik) + Python interfeys (qulaylik). Ikki dunyoning yaxshisi 30.1-bob.

6. Muhandislik saboqlari

  1. Abstraksiya: qulaylik ↔ nazorat/tezlik
  2. Avtomatik — qulaylik, xatosiz, sekinroq
  3. Qo'lda — tezlik/nazorat, xato yuki
  4. Kontekst tanlaydi (ilova/yadro)
  5. Eng yaxshisi — qatlam (C yadro + Python)

7. Xulosa

  1. GC — qulaylik uchun nazorat/tezlik to'lovi
  2. C API — nazorat/tezlik, lekin xato yuki
  3. Abstraksiya savdosi (kontekst tanlaydi)
  4. Qatlam eng yaxshi (numpy)

Nimani mustahkamlaydi: 2.3, 2.5-bo'limlar.


Xulosa

Bu darsda CPython C API asoslarini o'rgandik.

Eng muhim uch fikr:

  1. C API va PyObject. CPython C API — CPython interpretatori bilan C darajasida ishlash interfeysi: C kodidan Python obyektlarini yaratish, o'zgartirish (ctypes/cffi 30.3-4 — tashqi C — teskarisi, C dan Python ichiga); C kengaytma (30.6 — numpy, lxml) asosi. PyObject — har Python obyektinin C ko'rinishi: int, str, list — hammasi PyObject *; har birida tur (ob_type) + havolalar soni (ob_refcnt). Python "hamma narsa obyekt" — C darajasida PyObject.

  2. Havola hisobi, API funksiya, GIL. Havolalar hisobi (reference counting) — CPython xotira boshqaruvi: Py_INCREF (+1), Py_DECREF (-1), 0 → obyekt o'chadi; C API'da qo'lda (xato: DECREF unutish → oqma, ortiqcha DECREF → crash). API funksiyalar — Py<Tur>_<Amal> naqsh (PyLong_FromLong — int, PyUnicode_FromString — str, PyList_New — list). GIL (Global Interpreter Lock) — bir vaqtda bir ip (havola hisobi xavfsizligi); uzoq C amalda bo'shatish mumkin (Py_BEGIN_ALLOW_THREADS — parallel C, numpy).

  3. Tuzoqlar va Python ning C darajasi. C API tuzoqlari: havola oqmasi/ortiqcha DECREF (crash), NULL tekshirmaslik, GIL xatosi (poyga), versiya bog'liqligi, murakkablik; C API qiyin, xatoga moyil — faqat kerak bo'lsa (numpy darajasi), ko'pincha Cython 30.7-bob/cffi 30.4-bob soddaroq. C API — Python'ning C darajasi (interpretator ichki mexanizmi: PyObject, havola hisobi, GIL); Python "sehri"ni ochadi (obyekt nima, qachon o'chadi, nega bir ip). Avtomatik xotira (GC — qulaylik) va qo'lda (C API — nazorat/tezlik) — abstraksiya savdosi; eng yaxshisi ko'pincha qatlam (numpy — C yadro + Python interfeys).

Keyingi darsda C kengaytmasi yozishni o'rganamiz: C API bilan to'liq Python moduli yaratish — modul strukturasi (PyModuleDef), funksiya jadvali (PyMethodDef) va C dan Python'ga import qilinadigan haqiqiy kengaytma.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
30.5-dars: CPython C API asoslari — IlmHamroh