Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. CPython C API nima
- 2.2. PyObject — har narsa obyekt
- 2.3. Havolalar hisobi (reference counting)
- 2.4. API funksiyalari (obyekt yaratish)
- 2.5. GIL (Global Interpreter Lock)
- 2.6. C API amaliyoti
- 2.7. C API tuzoqlari
- 2.8. C API — Python ning C darajasi
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — PyObject (tur + havola)
- Misol 2 — Havolalar hisobi (INCREF/DECREF)
- Misol 3 — API funksiyalari (obyekt yaratish)
- Misol 4 — GIL (bir ip)
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
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 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:
/* 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:
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:
/* 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
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
/* 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 soddaroq4. Batafsil misollar
C API C kompilyator/CPython ichini talab qiladi; misollar C API mantiqini (deterministik) modellashtiradi.
Misol 1 — PyObject (tur + havola)
"""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:
=== 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)
"""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:
=== 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)
"""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:
=== 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)
"""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:
=== 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)
PyObject *o = PyLong_FromLong(5); // DECREF yo'q // ⚠️
PyObject *o = PyLong_FromLong(5); ...; Py_DECREF(o); // ✅2. Ortiqcha DECREF (crash)
Py_DECREF(o); Py_DECREF(o); // ikki marta (crash) // ⚠️
// havolani to'g'ri hisobla (bir marta) // ✅3. NULL tekshirmaslik
PyObject *o = PyList_GetItem(...); o->... // NULL bo'lsa crash // ⚠️
if (o == NULL) { /* xato */ } // ✅4. GIL bo'shatib Python obyektga tegish
Py_BEGIN_ALLOW_THREADS PyList_Append(...) // poyga // ⚠️
// GIL bo'shatilganda faqat C (Python obyekt tegma) // ✅5. Tur tekshirmaslik
PyLong_AsLong(str_obj) // str'da int amal (xato) // ⚠️
if (PyLong_Check(o)) { PyLong_AsLong(o); } // ✅6. C API oddiy ishga
// oddiy funksiyaga to'liq C API (ortiqcha, qiyin) // ⚠️
// Cython 30.7-bob yoki cffi 30.4-bob soddaroq // ✅7. Versiya farqini e'tiborsiz
// 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
Havolani to'g'ri (INCREF/DECREF muvozanat).
NULL tekshirish (API xatosi).
Tur tekshirish (PyLong_Check).
GIL (uzoq C amalda bo'shat, ehtiyot).
Versiyaga mos (stable ABI).
Soddaroq muqobil (Cython/cffi — ko'pincha).
C API faqat kerak bo'lsa (numpy darajasi).
Xotira oqmasini tekshir (havola audit).
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
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
- Python ichi bilan C darajada ishlash
- C API teskari (C dan Python ichiga)
- Har Python obyektining C ko'rinishi
- Tur (ob_type) + havolalar soni (refcnt)
- Obyektga nechta havola (xotira boshqaruvi)
- Havola qo'shildi (+1)
- Obyekt o'chadi (xotira bo'shaydi)
- Py
_ (PyLong_FromLong) - Global qulf (bir vaqtda bir ip)
- Havola hisobi xavfsizligi
- Uzoq C amalda (parallel)
- Yo'q (qiyin, xatoga moyil)
Vazifa 2: Xatolarni tuzating
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 APIJavoblar
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:
- Tur
- Havola soni
- int/str/list
- Universal
Vazifa 4: Havola
Modellang:
- INCREF
- DECREF
- 0 → o'chadi
- Oqma
Vazifa 5: API funksiya
Modellang:
- Yaratish
- O'qish
- Naqsh
- PyObject
Vazifa 6: GIL
Modellang:
- Bir ip
- Band
- Bo'shatish
- 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
- Abstraksiya: qulaylik ↔ nazorat/tezlik
- Avtomatik — qulaylik, xatosiz, sekinroq
- Qo'lda — tezlik/nazorat, xato yuki
- Kontekst tanlaydi (ilova/yadro)
- Eng yaxshisi — qatlam (C yadro + Python)
7. Xulosa
- GC — qulaylik uchun nazorat/tezlik to'lovi
- C API — nazorat/tezlik, lekin xato yuki
- Abstraksiya savdosi (kontekst tanlaydi)
- 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:
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 — hammasiPyObject *; har birida tur (ob_type) + havolalar soni (ob_refcnt). Python "hamma narsa obyekt" — C darajasidaPyObject.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).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.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!