Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. PyO3 nima
- 2.2. #[pyfunction] — funksiyani ochish
- 2.3. #[pymodule] — modul
- 2.4. Avtomatik tur o'girish
- 2.5. #[pyclass] — Rust klass
- 2.6. PyO3 amaliyoti
- 2.7. PyO3 vs C kengaytma
- 2.8. PyO3 — Rust va Python zamonaviy ko'prigi
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — #[pyfunction] (atribut)
- Misol 2 — Avtomatik tur o'girish
- Misol 3 — #[pyclass] (Rust struct → klass)
- Misol 4 — PyO3 vs C kengaytma (kod miqdori)
- 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.10-dars: PyO3 — Rust moduli
30-QISM — PYTHON VA BOSHQA TILLAR · 10-dars
1. Kirish va motivatsiya
Rust nega Python uchun jozibali ekanini 30.9-bob ko'rdik: C tezligi + xotira xavfsizligi. Endi ularni birlashtiramiz — Rust'da yozilgan funksiyani Python'dan chaqiriladigan qilamiz. Bu PyO3 kutubxonasi bilan bo'ladi: Rust funksiyasiga #[pyfunction] deb belgi (atribut) qo'yasiz, modulga #[pymodule] — PyO3 qolganini avtomatik qiladi (Python obyektlariga o'girish, C API — 30.5, hammasi yashirin). C kengaytmasi 30.6-bob qanchalik qiyin bo'lsa (PyObject, havolalar, funksiya jadvallari qo'lda), PyO3 shunchalik oson: Rust yozasiz, #[pyfunction] qo'yasiz, tayyor. PyO3 — Rust va Python o'rtasidagi zamonaviy, qulay ko'prik. polars, pydantic-core shu bilan qurilgan.
PyO3 — Rust va Python o'rtasida bog'lovchi kutubxona: #[pyfunction] (Rust funksiyani Python'ga ochish — atribut/dekorator), #[pymodule] (Rust modulini Python moduliga), avtomatik o'girish (Rust turlari ↔ Python obyektlari — C API 30.5 yashirin), #[pyclass] (Rust struct'ni Python klass'ga). Foydalanish: tez+xavfsiz kengaytma (Rust yadro), Python interfeys. Bu 30.9 (Rust — nega), 30.6 (C kengaytma — qiyin muqobil) bilan bog'liq. Bu 30.9 (Rust), 30.11 (maturin — yig'ish) bilan bog'liq. PyO3 — Rust'ni Python'ga. Atributlar. Oson.
Real vaziyat. Bir jamoa masofa hisobinit (koordinatalar — million juftlik, CPU-og'ir 29.2) tezlashtirmoqchi edi. Rust tanlandi (30.9 — tez+xavfsiz). PyO3 bilan: Rust'da masofa(a, b) funksiyasi yozildi, ustiga #[pyfunction] qo'yildi, modulga #[pymodule]. PyO3 qolganini avtomatik qildi (Python float ↔ Rust f64, C API yashirin). Python'dan import geo; geo.masofa(...) — oddiy. C kengaytma (30.6 — PyObject, havola qo'lda) bo'lsa, o'nlab qator murakkab kod kerak edi; PyO3 bilan bir atribut. PyO3 — Rust kengaytma, minimal murakkablik.
Bu darsda PyO3 bilan Rust modulini o'rganamiz.
Bu darsda:
- PyO3 nima
- #[pyfunction] — funksiyani ochish
- #[pymodule] — modul
- Avtomatik tur o'girish
- #[pyclass] — Rust klass
- PyO3 amaliyoti
- PyO3 vs C kengaytma
- Amaliy: PyO3 modeli
ℹ PyO3 Rust/kompilyator talab qiladi; misollar PyO3 struktura mantiqini (deterministik) modellashtiradi.
2. Nazariya — chuqur tushuntirish
2.1. PyO3 nima
Rust'ni Python'ga bog'lash:
// mening_modul (Rust — PyO3 bilan)
use pyo3::prelude::*;
#[pyfunction] // Python'ga ochish
fn qoshish(a: i64, b: i64) -> i64 {
a + b // Rust (tez + xavfsiz)
}
#[pymodule] // Python moduli
fn mening_modul(m: &Bound<PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(qoshish, m)?)?;
Ok(())
} PyO3 — Rust va Python o'rtasida bog'lovchi kutubxona: Rust kodini Python'dan import qilinadigan qiladi, minimal kod bilan (atributlar — #[pyfunction], #[pymodule]). Sabab: C kengaytma 30.6-bob qiyin (PyObject, havola, jadval qo'lda — C API 30.5); PyO3 buni avtomatlashtiradi (Rust yozasiz, atribut qo'yasiz, PyO3 C API'ni yaratadi — yashirin). Bu Cython (30.7 — Python'ga C tezlik) ning Rust ekvivalenti (Rust'ga Python interfeys). PyO3 tez (Rust 30.9) + xavfsiz + oson (atribut). polars, pydantic-core PyO3 bilan. PyO3 — Rust'ni Python'ga. Atributlar. Oson ko'prik.
2.2. #[pyfunction] — funksiyani ochish
Rust funksiyani Python'ga:
#[pyfunction] // bu atribut — Python'ga ochadi
fn kvadrat(x: f64) -> f64 {
x * x
}
// Python'da: modul.kvadrat(3.0) → 9.0
// PyO3 avtomatik: Python float ↔ Rust f64 #[pyfunction] — PyO3'ning asosiy atributi: Rust funksiyasini Python'ga ochadi (Python'dan chaqiriladigan). Sabab: oddiy Rust funksiya Python'dan ko'rinmaydi; #[pyfunction] atributi PyO3'ga "bu funksiya Python'ga chiqsin" deydi (PyO3 kerakli C API kodini avtomatik yaratadi — argument o'girish, natija o'girish). Bu C kengaytmadagi PyMethodDef (30.6 — funksiya jadvali qo'lda) ning avtomatik ekvivalenti (atribut bir qator). Foydalanish: har Python'ga kerakli Rust funksiyaga #[pyfunction]. #[pyfunction] — funksiyani ochish (atribut). Avtomatik C API. PyMethodDef ekvivalenti.
2.3. #[pymodule] — modul
Rust modulini Python moduliga:
#[pymodule] // Python moduli
fn geo(m: &Bound<PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(masofa, m)?)?; // funksiya qo'shish
m.add_function(wrap_pyfunction!(burchak, m)?)?;
Ok(())
}
// Python'da: import geo; geo.masofa(...) #[pymodule] — PyO3 modul atributi: Rust funksiyasini Python moduliga aylantiradi (funksiyalarni ro'yxatlaydi). Sabab: Python modul kerak (import geo); #[pymodule] funksiyasi modulni ta'riflaydi — m.add_function bilan har #[pyfunction] ni qo'shadi (Python'ga ko'rinadigan). Bu C kengaytmadagi PyModuleDef + PyInit (30.6 — modul + init qo'lda) ning avtomatik ekvivalenti. Modul nomi = funksiya nomi (geo). Foydalanish: bir #[pymodule], ichida funksiyalar qo'shiladi. #[pymodule] — modul (atribut). add_function. PyModuleDef ekvivalenti.
2.4. Avtomatik tur o'girish
PyO3 turlarni o'zi o'giradi:
Rust turi ↔ Python turi
i64, i32 ↔ int
f64 ↔ float
String, &str ↔ str
Vec<T> ↔ list
HashMap<K,V> ↔ dict
bool ↔ bool
PyO3 avtomatik o'giradi (dasturchi qo'lda emas) Avtomatik tur o'girish — PyO3'ning kuchli qulayligi: Rust turlarini Python turlariga (va aksincha) avtomatik o'giradi — i64↔int, f64↔float, String↔str, Vec↔list, HashMap↔dict. Sabab: C API'da 30.5-bob turlar qo'lda o'giriladi (PyLong_AsLong, PyLong_FromLong — 30.5); PyO3 buni avtomatik qiladi (Rust tur tizimi bilan — #[pyfunction] imzosi turlarni biladi). Bu C kengaytma (30.6 — qo'lda o'girish) dan keskin osonroq (avtomatik). Cheklov: murakkab tur (maxsus struct) uchun #[pyclass] 2.5-bob. Avtomatik o'girish — Rust ↔ Python turlar. Qo'lda emas. C API yashirin.
2.5. #[pyclass] — Rust klass
Rust struct'ni Python klass'ga:
#[pyclass] // Python klass
struct Nuqta {
#[pyo3(get, set)] // Python'dan o'qish/yozish
x: f64,
#[pyo3(get, set)]
y: f64,
}
#[pymethods] // klass metodlari
impl Nuqta {
#[new] // konstruktor
fn new(x: f64, y: f64) -> Self {
Nuqta { x, y }
}
}
// Python'da: n = Nuqta(1.0, 2.0); n.x #[pyclass] — Rust struct'ni Python klass'ga aylantirish: #[pyclass] (struct → klass), #[pyo3(get, set)] (maydon — Python'dan o'qish/yozish), #[pymethods] (metodlar bloki), #[new] (konstruktor — __init__). Sabab: ba'zan funksiya yetmaydi — obyekt kerak (holat, metodlar — 16-qism OOP); #[pyclass] Rust struct'ni to'liq Python klass qiladi (Python'dan Nuqta(1, 2), n.x, n.usul()). Bu C API'da 30.5-bob juda qiyin (klass qo'lda — o'nlab qator); PyO3'da atributlar. Foydalanish: holat/metod kerak (klass), oddiy hisob (funksiya). #[pyclass] — Rust struct → Python klass. Atributlar. OOP.
2.6. PyO3 amaliyoti
PyO3 amaliyotlari: #[pyfunction] (funksiya — Python'ga); #[pymodule] (modul — funksiyalar qo'sh); avtomatik tur (Rust ↔ Python — qo'lda emas); #[pyclass] (obyekt kerak — struct → klass); maturin (30.11 — yig'ish, .whl); xato boshqarish (PyResult — Rust xatosi → Python istisno); ownership (30.9 — Rust qoidalari, PyO3 bilan ham); bottleneck (29.2 — faqat sekin joy Rust). Tuzoqlar: Rust o'rganish (ownership — vaqt), ortiqcha (oddiy ishga — Cython 30.7 osonroq), tur mosligi (murakkab tur — #[pyclass]). Amaliyot — atributlar (pyfunction, pymodule, pyclass), avtomatik tur, maturin. PyO3 — Rust'ni Python'ga oson.
2.7. PyO3 vs C kengaytma
| Jihat | C kengaytma (30.6) | PyO3 (Rust) |
|---|---|---|
| Til | C (xavfli) | Rust (xavfsiz) |
| Funksiya ochish | PyMethodDef (qo'lda) | #[pyfunction] (atribut) |
| Modul | PyModuleDef+PyInit (qo'lda) | #[pymodule] (atribut) |
| Tur o'girish | Qo'lda (PyLong_...) | Avtomatik |
| Havola | INCREF/DECREF (qo'lda) | Avtomatik (ownership) |
| Qiyinlik | Yuqori | O'rta (Rust o'rganish) |
PyO3 vs C kengaytma: C kengaytma (30.6 — C til xavfli, PyMethodDef/PyModuleDef/PyInit qo'lda, tur o'girish qo'lda, havola INCREF/DECREF qo'lda — 30.5, ko'p murakkab kod); PyO3 (Rust — xavfsiz 30.9, atributlar #[pyfunction]/#[pymodule], tur o'girish avtomatik, havola avtomatik — Rust ownership; ancha kamroq kod, xavfsizroq). Sabab: PyO3 C API murakkabligini yashiradi (Rust + atribut), C kengaytma ochiq (qo'lda). Farq: PyO3 xavfsiz (Rust), oson (atribut), C kengaytma xavfli (C), qiyin (qo'lda). PyO3'da asosiy sarmoya — Rust o'rganish (ownership 30.9), lekin C API osonroq. PyO3 — Rust + atribut (oson, xavfsiz). C kengaytma — C + qo'lda. PyO3 afzal (zamonaviy).
2.8. PyO3 — Rust va Python zamonaviy ko'prigi
PyO3 asosiy g'oyasi — Rust va Python zamonaviy ko'prigi: Rust'ning tezlik va xavfsizligini 30.9-bob Python'ning qulayligi bilan atributlar orqali birlashtiradi (#[pyfunction], #[pymodule], #[pyclass] — PyO3 qolganini avtomatik). Bu C kengaytma (30.6 — C API qo'lda, qiyin, xavfli) ning zamonaviy, xavfsiz, oson muqobili. PyO3 C API murakkabligini (PyObject, havola, jadval — 30.5) yashiradi (Rust tur tizimi + atribut → avtomatik). Bu 30.1 (to'g'ri til to'g'ri ishga — Rust yadro + Python qobiq) ning zamonaviy amalga oshirilishi; polars, pydantic-core, tokenizers PyO3 bilan (tez + xavfsiz + oson). Rust o'rganish sarmoya (ownership), lekin natija kuchli (C tezlik, C xavfsizlik emas, oson interfeys). PyO3 — Rust ↔ Python (atribut). Zamonaviy ko'prik.
3. Tez ma'lumotnoma
// PYO3 — Rust'ni Python'ga (mening_modul)
use pyo3::prelude::*;
// #[pyfunction] — funksiyani Python'ga ochish
#[pyfunction]
fn qoshish(a: i64, b: i64) -> i64 { a + b }
// #[pymodule] — Python moduli (funksiyalar qo'shish)
#[pymodule]
fn mening_modul(m: &Bound<PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(qoshish, m)?)?;
Ok(())
}
// #[pyclass] — Rust struct → Python klass
#[pyclass]
struct Nuqta { #[pyo3(get, set)] x: f64, #[pyo3(get, set)] y: f64 }
#[pymethods]
impl Nuqta {
#[new]
fn new(x: f64, y: f64) -> Self { Nuqta { x, y } }
}AVTOMATIK TUR O'GIRISH:
i64/i32 ↔ int · f64 ↔ float · String/&str ↔ str
Vec<T> ↔ list · HashMap ↔ dict · bool ↔ bool
PYO3 vs C KENGAYTMA:
C — qo'lda (PyMethodDef, PyLong_..., INCREF) — xavfli
PyO3 — atribut (#[pyfunction]), avtomatik tur — xavfsiz
QOIDA: atribut (pyfunction/pymodule/pyclass) + avtomatik tur + maturin (30.11)PyO3 xulosasi
PyO3 — Rust'ni Python'ga bog'lash (atributlar bilan, oson)
#[pyfunction] — funksiyani ochish (PyMethodDef avtomatik)
#[pymodule] — Python moduli (funksiyalar qo'shish)
Avtomatik tur — Rust ↔ Python (qo'lda emas, C API yashirin)
#[pyclass] — Rust struct → Python klass (OOP) · maturin yig'adi4. Batafsil misollar
PyO3 Rust/kompilyator talab qiladi; misollar PyO3 struktura mantiqini (deterministik) modellashtiradi.
Misol 1 — #[pyfunction] (atribut)
"""#[pyfunction]: Rust funksiyani Python'ga ochish (model)."""
def pyfunction_model(nom: str, rust_imzo: str) -> dict:
return {
"nom": nom,
"rust_imzo": rust_imzo,
"atribut": "#[pyfunction]",
"python_korinish": True,
}
def main() -> None:
print("=== 1. Rust funksiya ===")
f = pyfunction_model("kvadrat", "fn kvadrat(x: f64) -> f64")
print(f" {f['rust_imzo']}")
print("\n=== 2. Atribut ===")
print(f" {f['atribut']} (Python'ga ochadi)")
print("\n=== 3. Python'da ko'rinishi ===")
print(f" modul.{f['nom']}3.0-bob → 9.0")
print("\n=== 4. C kengaytma farqi ===")
print(" C: PyMethodDef qo'lda (jadval)")
print(" PyO3: #[pyfunction] (bir atribut)")
print(" ⭐ #[pyfunction] — funksiyani ochish (avtomatik)")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Rust funksiya ===
fn kvadrat(x: f64) -> f64
=== 2. Atribut ===
#[pyfunction] (Python'ga ochadi)
=== 3. Python'da ko'rinishi ===
modul.kvadrat(3.0) → 9.0
=== 4. C kengaytma farqi ===
C: PyMethodDef qo'lda (jadval)
PyO3: #[pyfunction] (bir atribut)
⭐ #[pyfunction] — funksiyani ochish (avtomatik)Nima ko'rsatdi: 2.1, 2.2-bo'limlar.
Misol 2 — Avtomatik tur o'girish
"""Avtomatik tur: Rust ↔ Python o'girish jadvali (model)."""
TUR_JADVAL = {
"i64": "int",
"f64": "float",
"String": "str",
"Vec<T>": "list",
"HashMap<K,V>": "dict",
"bool": "bool",
}
def main() -> None:
print("=== 1. Tur o'girish jadvali ===")
for rust, python in TUR_JADVAL.items():
print(f" {rust:14} ↔ {python}")
print("\n=== 2. Avtomatik ===")
print(" PyO3 o'zi o'giradi (dasturchi qo'lda emas)")
print("\n=== 3. C API farqi 30.5-bob ===")
print(" C: PyLong_AsLong / PyLong_FromLong (qo'lda)")
print(" PyO3: imzodan avtomatik (Rust tur tizimi)")
print("\n=== 4. Cheklov ===")
print(" murakkab tur → #[pyclass]")
print(" ⭐ Avtomatik tur — Rust ↔ Python (C API yashirin)")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Tur o'girish jadvali ===
i64 ↔ int
f64 ↔ float
String ↔ str
Vec<T> ↔ list
HashMap<K,V> ↔ dict
bool ↔ bool
=== 2. Avtomatik ===
PyO3 o'zi o'giradi (dasturchi qo'lda emas)
=== 3. C API farqi 30.5-bob ===
C: PyLong_AsLong / PyLong_FromLong (qo'lda)
PyO3: imzodan avtomatik (Rust tur tizimi)
=== 4. Cheklov ===
murakkab tur → #[pyclass]
⭐ Avtomatik tur — Rust ↔ Python (C API yashirin)Nima ko'rsatdi: 2.4-bo'lim.
Misol 3 — #[pyclass] (Rust struct → klass)
"""#[pyclass]: Rust struct'ni Python klass'ga (model)."""
class PyclassModel:
def __init__(self, struct_nomi: str, maydonlar: list) -> None:
self.struct_nomi = struct_nomi
self.maydonlar = maydonlar
self.atributlar = ["#[pyclass]", "#[pymethods]", "#[new]"]
def main() -> None:
n = PyclassModel("Nuqta", ["x: f64", "y: f64"])
print("=== 1. Rust struct ===")
print(f" struct {n.struct_nomi} {{ {', '.join(n.maydonlar)} }}")
print("\n=== 2. Atributlar ===")
for a in n.atributlar:
print(f" {a}")
print("\n=== 3. Python'da ===")
print(f" n = {n.struct_nomi}(1.0, 2.0)")
print(" n.x # get/set atributi")
print("\n=== 4. OOP ===")
print(" struct + metodlar → Python klass (holat)")
print(" ⭐ #[pyclass] — Rust struct → Python klass")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Rust struct ===
struct Nuqta { x: f64, y: f64 }
=== 2. Atributlar ===
#[pyclass]
#[pymethods]
#[new]
=== 3. Python'da ===
n = Nuqta(1.0, 2.0)
n.x # get/set atributi
=== 4. OOP ===
struct + metodlar → Python klass (holat)
⭐ #[pyclass] — Rust struct → Python klassNima ko'rsatdi: 2.5-bo'lim.
Misol 4 — PyO3 vs C kengaytma (kod miqdori)
"""PyO3 vs C: bir funksiya uchun qadamlar soni (model)."""
def qadamlar(usul: str) -> dict:
if usul == "C kengaytma":
q = ["C funksiya", "PyArg_ParseTuple", "PyLong_FromLong",
"PyMethodDef", "PyModuleDef", "PyInit", "INCREF/DECREF"]
else: # PyO3
q = ["Rust funksiya", "#[pyfunction]", "#[pymodule] qo'shish"]
return {"usul": usul, "qadamlar": q}
def main() -> None:
print("=== 1. C kengaytma qadamlari ===")
c = qadamlar("C kengaytma")
for i, q in enumerate(c["qadamlar"], 1):
print(f" {i}. {q}")
print(f" jami: {len(c['qadamlar'])} qadam (qo'lda)")
print("\n=== 2. PyO3 qadamlari ===")
p = qadamlar("PyO3")
for i, q in enumerate(p["qadamlar"], 1):
print(f" {i}. {q}")
print(f" jami: {len(p['qadamlar'])} qadam (atribut)")
print("\n=== 3. Farq ===")
print(f" C: {len(c['qadamlar'])} qo'lda vs PyO3: {len(p['qadamlar'])} atribut")
print("\n=== 4. Qo'shimcha ===")
print(" PyO3 xavfsiz (Rust), C xavfli (qo'lda havola)")
print(" ⭐ PyO3 — kamroq kod, xavfsizroq (atribut)")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. C kengaytma qadamlari ===
1. C funksiya
2. PyArg_ParseTuple
3. PyLong_FromLong
4. PyMethodDef
5. PyModuleDef
6. PyInit
7. INCREF/DECREF
jami: 7 qadam (qo'lda)
=== 2. PyO3 qadamlari ===
1. Rust funksiya
2. #[pyfunction]
3. #[pymodule] qo'shish
jami: 3 qadam (atribut)
=== 3. Farq ===
C: 7 qo'lda vs PyO3: 3 atribut
=== 4. Qo'shimcha ===
PyO3 xavfsiz (Rust), C xavfli (qo'lda havola)
⭐ PyO3 — kamroq kod, xavfsizroq (atribut)Nima ko'rsatdi: 2.7-bo'lim.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "PyO3 = C kengaytma qiyinligi" | PyO3 oson (atribut) |
| "Turlarni qo'lda o'gir" | Avtomatik (Rust ↔ Python) |
| "#[pyfunction] keraksiz" | Funksiyani Python'ga ochadi |
| "Havolani qo'lda hisobla" | Avtomatik (Rust ownership) |
| "Faqat funksiya" | #[pyclass] (klass ham) |
| "PyO3 xavfli (C kabi)" | Rust xavfsiz (ownership) |
| "Rust o'rganishsiz" | Ownership o'rganish kerak |
| "C API ko'rinadi" | Yashirin (PyO3 avtomatik) |
6. Keng tarqalgan xatolar va yechimlari
1. #[pyfunction] unutish
fn qoshish(...) {...} // atributsiz (Python ko'rmaydi) // ⚠️
#[pyfunction] fn qoshish(...) {...} // atribut // ✅2. #[pymodule]ga qo'shmaslik
// #[pyfunction] bor, lekin modulga add_function yo'q // ⚠️
m.add_function(wrap_pyfunction!(qoshish, m)?)?; // ✅3. Murakkab turga avtomatik kutish
fn f(x: MaxsusStruct) // avtomatik o'girmaydi // ⚠️
#[pyclass] struct MaxsusStruct {...} // pyclass // ✅4. Xatoni panic bilan (crash)
fn f() { panic!(...) } // Rust panic → crash // ⚠️
fn f() -> PyResult<...> { Err(...) } // Python istisno // ✅5. Oddiy ishga PyO3 (ortiqcha)
# kichik tezlashtirishga Rust+PyO3 (o'rganish) # ⚠️
# Cython 30.7-bob — osonroq, tez natija # ✅6. maturinsiz yig'ish
# Rust kod bor, lekin .whl yo'q (yig'ilmagan) # ⚠️
# maturin 30.11-bob — yig'ish, .whl # ✅7. get/set unutish (pyclass)
#[pyclass] struct N { x: f64 } // n.x ishlamaydi // ⚠️
#[pyo3(get, set)] x: f64 // o'qish/yozish // ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 30.9-dars (o'tilgan): Rust — nega Python bilan
- 30.11-dars: maturin — Rust yig'ish
- 30.6-dars (o'tilgan): C kengaytma — qiyin muqobil
- 30.7-dars (o'tilgan): Cython — oson muqobil
- 30.5-dars (o'tilgan): C API — PyO3 yashiradi
8. Eng yaxshi amaliyotlar
#[pyfunction] (funksiyani Python'ga ochish).
#[pymodule]ga add_function (qo'shish).
Avtomatik tur (Rust ↔ Python — qo'lda emas).
#[pyclass] (obyekt/holat kerak).
PyResult (xato — Python istisno, panic emas).
maturin 30.11-bob — yig'ish, .whl.
Bottleneck 29.2-bob Rust, qolgani Python.
Oddiy ishga Cython (PyO3 — jiddiy/xavfsizlik).
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # PyO3 nima?
2. # PyO3 nega oson?
3. # #[pyfunction] nima?
4. # #[pymodule] nima?
5. # add_function nima?
6. # avtomatik tur nima?
7. # i64 ↔ ?
8. # Vec<T> ↔ ?
9. # #[pyclass] nima?
10. # #[new] nima?
11. # PyO3 vs C kengaytma?
12. # xato qanday?Javoblar
- Rust'ni Python'ga bog'lash kutubxonasi
- Atributlar (PyO3 C API'ni avtomatik)
- Rust funksiyani Python'ga ochish (atribut)
- Rust modulini Python moduliga
- Funksiyani modulga qo'shish
- Rust ↔ Python turlar (avtomatik)
- int
- list
- Rust struct → Python klass
- Konstruktor (init)
- PyO3 atribut/avtomatik/xavfsiz, C qo'lda/xavfli
- PyResult (Err → Python istisno)
Vazifa 2: Xatolarni tuzating
1. fn qoshish(...) # atributsiz
2. # modulga add_function yo'q
3. fn f(x: MaxsusStruct) # avtomatik kutish
4. fn f() { panic!() } # xato
5. # kichik ishga PyO3Javoblar
1. #[pyfunction] fn qoshish(...)
2. m.add_function(wrap_pyfunction!(...))
3. #[pyclass] struct MaxsusStruct
4. PyResult + Err (Python istisno)
5. Cython (osonroq)Vazifa 3: #[pyfunction]
Modellang:
- Rust funksiya
- Atribut
- Python ko'rinish
- C farqi
Vazifa 4: Avtomatik tur
Modellang:
- i64/int
- String/str
- Vec/list
- Avtomatik
Vazifa 5: #[pyclass]
Modellang:
- Struct
- Atributlar
- Konstruktor
- Python klass
Vazifa 6: PyO3 vs C
Modellang:
- C qadamlar
- PyO3 qadamlar
- Farq
- Xavfsizlik
Vazifa 7: O'ylash
PyO3 atributlar (#[pyfunction]) orqali murakkab C API kodini (PyObject, havolalar, jadvallar) yashiradi — dasturchi bir atribut yozadi, PyO3 o'nlab qatorni avtomatik yaratadi. Nima uchun "deklarativ" yondashuv (nima kerakligini aytish — #[pyfunction]) "imperativ" yondashuvdan (qanday qilishni yozish — C API qadamlari) ko'pincha yaxshiroq, va nega "atribut/dekorator" abstraksiyasi kuchli vosita?
Javob
Qisqa javob: "Deklarativ" yondashuv imperativdan ko'pincha yaxshiroq, chunki: deklarativ niyatni ifodalaydi ("bu funksiya Python'ga chiqsin" — #[pyfunction]), imperativ mexanizmni (qanday chiqarish — PyMethodDef, PyLong_..., INCREF, o'nlab qadam); niyat qisqa, aniq, o'qiladi (nima kerakligi ko'rinadi), mexanizm uzun, murakkab, xatoga moyil (qanday qilish yashiringan bo'lishi kerak). "Nega deklarativ yaxshiroq": (1) kamroq kod — #[pyfunction] (bir qator) vs C API (o'nlab qator); kamroq kod = kamroq xato, kamroq saqlash; (2) niyat ko'rinadi — #[pyfunction] o'qiganda "Python'ga ochiladi" darhol ravshan; C API'da niyat qadamlar ichida yo'qoladi (nima uchun bu INCREF?); (3) mexanizm yashirin — "qanday" (C API) PyO3 zimmasida (mutaxassis bir marta to'g'ri yozgan, hamma foydalanadi); dasturchi "nima"ga e'tibor beradi (biznes mantiq); (4) xato kamayadi — mexanizm (havola, jadval) yashirin → dasturchi xato qila olmaydi (PyO3 to'g'ri qiladi). "Nega atribut/dekorator kuchli": atribut — metama'lumot (kodga "belgi" qo'yish — bu funksiya maxsus); u kodni o'zgartirmasdan yangi xatti-harakat qo'shadi (PyO3 atributni ko'rib, kod yaratadi); bu ajratish (funksiya mantig'i alohida, Python'ga ochish alohida — atribut); qayta ishlatiladi (har funksiyaga bir xil atribut). Bu umumiy tamoyil: deklarativ (SQL — "nima kerak", nima qatorlar; HTML — "nima ko'rsatilsin"; Docker — "nima holat" 28.1) imperativdan (har qadamni yozish) ko'pincha ustun — niyat aniq, mexanizm yashirin, kamroq xato. Boshqa misollar: dekorator (@property, @staticmethod — 16-qism), type hint (x: int — niyat), routing (@app.route). Muhandislik saboqlari: niyatni ifodala (nima), mexanizmni yashir (qanday); deklarativ — qisqa, o'qiladi, kamroq xato; atribut/dekorator — metama'lumot (kodni o'zgartirmasdan xatti-harakat); ajratish (mantiq vs infratuzilma — atribut); mutaxassis mexanizmni bir marta (hamma foydalanadi). PyO3 misolida: #[pyfunction] niyat (Python'ga ochish); PyO3 mexanizm (C API) — dasturchi C API bilmasligi mumkin (niyatga e'tibor).
1. Nega deklarativ yaxshiroq
- Niyatni ifodalaydi (nima kerak — #[pyfunction])
- Kamroq kod (atribut vs o'nlab qator)
- Niyat ko'rinadi (o'qiladi)
- Mexanizm yashirin (xato kamayadi)
2. Nega atribut/dekorator kuchli
- Metama'lumot (kodga belgi — maxsus)
- Kodni o'zgartirmasdan xatti-harakat
- Ajratish (mantiq alohida, ochish alohida)
- Qayta ishlatiladi (bir xil atribut)
3. Deklarativ vs imperativ
| Jihat | Deklarativ (#[pyfunction]) | Imperativ (C API) |
|---|---|---|
| Ifoda | Niyat (nima) | Mexanizm (qanday) |
| Uzunlik | Qisqa | Uzun |
| Xato | Kam (yashirin) | Ko'p (qo'lda) |
4. Boshqa misollar
SQL (nima qatorlar), HTML (nima ko'rsatilsin), Docker (nima holat), dekorator (@property), type hint (x: int).
5. Muhandislik saboqlari
- Niyatni ifodala (nima), mexanizm yashir (qanday)
- Deklarativ — qisqa, o'qiladi, kamroq xato
- Atribut/dekorator — metama'lumot (xatti-harakat)
- Ajratish (mantiq vs infratuzilma)
- Mutaxassis mexanizmni bir marta
6. Xulosa
- Deklarativ — niyat (nima), imperativ — mexanizm (qanday)
- #[pyfunction] — niyat, PyO3 — mexanizm (yashirin)
- Atribut kuchli — metama'lumot (kodni o'zgartirmasdan)
- Kamroq kod, kamroq xato, o'qiladi
Nimani mustahkamlaydi: 2.1, 2.7-bo'limlar.
Xulosa
Bu darsda PyO3 bilan Rust modulini o'rgandik.
Eng muhim uch fikr:
PyO3 va #[pyfunction]. PyO3 — Rust va Python o'rtasida bog'lovchi kutubxona: Rust kodini Python'dan
importqilinadigan qiladi atributlar bilan (#[pyfunction],#[pymodule]), C API murakkabligini yashirib.#[pyfunction]— Rust funksiyasini Python'ga ochadi (atribut; PyO3 kerakli C API kodini avtomatik yaratadi — argument/natija o'girish); C kengaytmadagiPyMethodDef(30.6 — jadval qo'lda) ning avtomatik ekvivalenti.#[pymodule]— Rust modulini Python moduliga (m.add_functionbilan funksiyalarni qo'shadi);PyModuleDef+PyInitavtomatik ekvivalenti.Avtomatik tur va #[pyclass]. Avtomatik tur o'girish — PyO3 Rust turlarini Python turlariga o'giradi (
i64↔int,f64↔float,String↔str,Vec↔list,HashMap↔dict); C API'da 30.5-bob qo'lda (PyLong_...), PyO3'da avtomatik (Rust tur tizimi — imzodan).#[pyclass]— Rust struct'ni Python klass'ga (#[pyclass]struct→klass,#[pyo3(get, set)]maydon,#[pymethods]metodlar,#[new]konstruktor); obyekt/holat kerak bo'lsa (OOP). Havola ham avtomatik (Rust ownership — INCREF/DECREF qo'lda emas).C kengaytma taqqoslash va zamonaviy ko'prik. PyO3 vs C kengaytma: C (C til xavfli, PyMethodDef/PyModuleDef/PyInit qo'lda, tur/havola qo'lda — ko'p murakkab kod), PyO3 (Rust xavfsiz, atributlar, tur/havola avtomatik — kamroq kod, xavfsizroq); asosiy sarmoya Rust o'rganish (ownership 30.9), lekin C API osonroq. PyO3 — Rust va Python zamonaviy ko'prigi (tezlik+xavfsizlik+qulaylik, atribut orqali); C kengaytma 30.6-bob ning zamonaviy muqobili; polars, pydantic-core, tokenizers PyO3 bilan. Deklarativ atribut (
#[pyfunction]— niyat) imperativ C API'dan (mexanizm — qadamlar) ustun (qisqa, o'qiladi, kamroq xato); atribut/dekorator — kuchli abstraksiya (metama'lumot, mantiq vs infratuzilma ajratiladi).
Keyingi darsda maturin bilan yig'ishni o'rganamiz: Rust+PyO3 kodini Python paketga (.whl) aylantirish — maturin develop/build, PyPI'ga chiqarish va foydalanuvchi Rust kompilyatorisiz o'rnatishi.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!