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

30.12-dars: C++ va pybind11

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


1. Kirish va motivatsiya

Rust'ni Python'ga PyO3 30.10-bob bilan bog'ladik. Lekin dunyoda ulkan C++ kod bazasi bor — o'yin dvigatellari, ilmiy kutubxonalar (OpenCV, Eigen), moliyaviy tizimlar. Bu C++ kodni Python'da ishlatish uchun pybind11 kutubxonasi bor — PyO3'ning C++ ekvivalenti. pybind11 zamonaviy C++ (C++11 va undan yuqori) imkoniyatlaridan foydalanadi: bir necha qator C++ kod bilan funksiya/klassni Python'ga ochadi, turlarni avtomatik o'giradi. C API 30.5-bob qanchalik qiyin bo'lsa, pybind11 shunchalik oson: m.def("qoshish", &qoshish) — tayyor. TensorFlow, PyTorch qismlari pybind11 bilan Python'ga bog'langan. Agar mavjud C++ kutubxonangiz bo'lsa yoki C++ tezligi kerak bo'lsa — pybind11 ideal ko'prik.

pybind11 — C++ va Python o'rtasida bog'lovchi kutubxona (faqat sarlavha — header-only): m.def (C++ funksiyani Python'ga ochish), py::class_ (C++ klassni Python'ga), avtomatik tur o'girish (C++ ↔ Python — STL turlar std::vector↔list), zamonaviy C++ (C++11+, template, lambda). Foydalanish: mavjud C++ kutubxona o'rash (OpenCV, Eigen), C++ tezlik. Bu PyO3 (30.10 — Rust ekvivalenti) ning C++ varianti. Bu 30.10 (PyO3), 30.5 (C API — pybind11 yashiradi) bilan bog'liq. pybind11 — C++ ni Python'ga. Header-only. Oson.

Real vaziyat. Jamoada katta C++ fizika kutubxonasi bor edi (yillar mehnati — tez, sinovdan o'tgan). Uni Python'da ishlatmoqchi edilar (tadqiqotchilar Python biladi, C++ emas). Qayta yozish — behuda (yillar). pybind11 qo'llandi: C++ funksiyalar m.def("simulyatsiya", &simulyatsiya) bilan Python'ga ochildi (bir necha qator), STL turlar avtomatik o'girildi (std::vector<double> ↔ list). Tadqiqotchilar import fizika — C++ ni ko'rmasdan, tez kutubxonani Python'da ishlatdi. pybind11 — mavjud C++ ni Python'ga (qayta yozishsiz).

Bu darsda C++ va pybind11 ni o'rganamiz.

Bu darsda:

  • pybind11 nima
  • m.def — funksiyani ochish
  • py::class_ — C++ klass
  • Avtomatik tur (STL)
  • Header-only qulaylik
  • pybind11 amaliyoti
  • pybind11 vs PyO3/Cython
  • Amaliy: pybind11 modeli

ℹ pybind11 C++ kompilyator talab qiladi; misollar pybind11 struktura mantiqini (deterministik) modellashtiradi.


2. Nazariya — chuqur tushuntirish

2.1. pybind11 nima

C++'ni Python'ga bog'lash:

cpp
// mening_modul.cpp — pybind11 bilan
#include <pybind11/pybind11.h>
namespace py = pybind11;

int qoshish(int a, int b) {
    return a + b;                      // oddiy C++
}

PYBIND11_MODULE(mening_modul, m) {     // Python moduli
    m.def("qoshish", &qoshish, "Ikki son yig'indisi");
}
// Python'da: import mening_modul; mening_modul.qoshish(3, 5)

pybind11 — C++ va Python o'rtasida bog'lovchi header-only kutubxona (faqat sarlavha fayllar — o'rnatish oson): C++ kodini Python'dan import qilinadigan qiladi, minimal kod bilan (m.def, PYBIND11_MODULE). Sabab: C API 30.5-bob qiyin (PyObject, havola qo'lda); pybind11 buni yashiradi (zamonaviy C++ — template, avtomatik tur). Bu PyO3 (30.10 — Rust) ning C++ ekvivalenti (bir xil g'oya, boshqa til). Foydalanish: mavjud C++ kutubxona (OpenCV, Eigen), C++ tezlik. TensorFlow, PyTorch qismlari pybind11 bilan. pybind11 — C++ ni Python'ga. Header-only. C API yashirin.

2.2. m.def — funksiyani ochish

C++ funksiyani Python'ga:

cpp
double kvadrat(double x) {
    return x * x;
}

PYBIND11_MODULE(mening_modul, m) {
    m.def("kvadrat", &kvadrat, "Sonning kvadrati");
    //     │          │          └─ hujjat (docstring)
    //     │          └─ C++ funksiya manzili (&)
    //     └─ Python'da ko'rinadigan nom
}

m.def — pybind11'ning asosiy usuli: C++ funksiyani Python'ga ochadi (m.def("nom", &funksiya, "hujjat")). Sabab: oddiy C++ funksiya Python'dan ko'rinmaydi; m.def uni ro'yxatga oladi (Python'ga chiqaradi — pybind11 kerakli C API'ni avtomatik yaratadi). Argumentlar: Python nomi ("kvadrat"), C++ funksiya manzili (&kvadrat), hujjat (docstring). Bu C kengaytmadagi PyMethodDef (30.6 — jadval qo'lda) va PyO3'ning #[pyfunction] 30.10-bob ekvivalenti (bir chaqiruv). Foydalanish: har Python'ga kerakli C++ funksiyaga m.def. m.def — funksiyani ochish. Nom + manzil + hujjat. PyMethodDef ekvivalenti.

2.3. py::class_ — C++ klass

C++ klassni Python'ga:

cpp
class Nuqta {
public:
    Nuqta(double x, double y) : x(x), y(y) {}
    double masofa() const { return std::sqrt(x*x + y*y); }
    double x, y;
};

PYBIND11_MODULE(geo, m) {
    py::class_<Nuqta>(m, "Nuqta")
        .def(py::init<double, double>())   // konstruktor
        .def("masofa", &Nuqta::masofa)     // metod
        .def_readwrite("x", &Nuqta::x)     // maydon
        .def_readwrite("y", &Nuqta::y);
}
// Python'da: n = geo.Nuqta(3, 4); n.masofa()

py::class_ — C++ klassni Python klass'ga bog'lash: py::class_<C++Klass>(m, "PythonNom"), keyin .def(py::init<...>()) (konstruktor), .def("metod", &Klass::metod) (metodlar), .def_readwrite("maydon", &Klass::maydon) (maydonlar). Sabab: ba'zan funksiya yetmaydi — obyekt kerak (holat, metodlar — 16-qism OOP); py::class_ C++ klassni to'liq Python klass qiladi. Bu PyO3'ning #[pyclass] 30.10-bob ekvivalenti (C++ varianti). .def zanjiri (chaining — konstruktor, metod, maydon). Foydalanish: C++ klass kerak (OpenCV Mat, Eigen Matrix). py::class_ — C++ klass → Python klass. Konstruktor + metod + maydon. #[pyclass] ekvivalenti.

2.4. Avtomatik tur (STL)

pybind11 turlarni o'giradi:

C++ turi              ↔  Python turi
   int, long           ↔  int
   double, float       ↔  float
   std::string         ↔  str
   std::vector<T>      ↔  list
   std::map<K,V>       ↔  dict
   std::pair<A,B>      ↔  tuple

// STL uchun: #include <pybind11/stl.h>

Avtomatik tur (STL) — pybind11 C++ turlarini Python turlariga o'giradi: asosiy (int↔int, double↔float, std::string↔str) va STL (std::vector↔list, std::map↔dict, std::pair↔tuple — #include <pybind11/stl.h> bilan). Sabab: C API'da 30.5-bob qo'lda o'girish; pybind11 avtomatik (C++ tur tizimi — template bilan). STL (Standard Template Library — C++ standart konteynerlar) keng ishlatiladi (vector, map); pybind11 ularni Python konteynerlariga o'giradi (list, dict). Bu PyO3 avtomatik turi 30.10-bob ning C++ ekvivalenti. Cheklov: STL uchun alohida sarlavha (stl.h). Avtomatik tur — C++ ↔ Python (STL bilan). Header qo'shish. Qo'lda emas.

2.5. Header-only qulaylik

Faqat sarlavha — kutubxonasiz:

pybind11 — header-only (faqat .h fayllar)
   yig'ish uchun kutubxona bog'lash SHART EMAS
   #include <pybind11/pybind11.h> — yetadi

O'rnatish: pip install pybind11
   yoki git submodule (sarlavhalar)

→ oddiy, portativ (faqat sarlavhalar)

Header-only qulaylik — pybind11 faqat sarlavha kutubxona (header-only — barcha kod .h fayllarda, .lib/.so bog'lash yo'q): #include <pybind11/pybind11.h> yetadi (alohida kutubxona bog'lamaydi). Sabab: an'anaviy C++ kutubxona yig'ilgan (.lib/.so) — bog'lash kerak (murakkab, versiya muammosi); header-only soddaroq (faqat sarlavha — kompilyator o'zi qo'shadi). O'rnatish: pip install pybind11 (sarlavhalar) yoki git submodule. Bu portativ (faqat sarlavha — har joyda ishlaydi). Cheklov: kompilyatsiya sekinroq (sarlavha har faylga — template). Header-only — faqat sarlavha (bog'lashsiz). Oddiy, portativ. pip install pybind11.

2.6. pybind11 amaliyoti

pybind11 amaliyotlari: m.def (funksiya — Python'ga); py::class_ (klass — konstruktor/metod/maydon); stl.h (STL avtomatik tur — #include <pybind11/stl.h>); PYBIND11_MODULE (modul); yig'ish (setup.py + pybind11, yoki CMake); hujjat (docstring — m.def uchinchi argument); argument nomi (py::arg("x") — nomli argument); mavjud C++ o'rash (asosiy foydalanish). Tuzoqlar: STL uchun stl.h unutish (o'girmaydi), C++ kompilyator (kerak), template kompilyatsiya (sekinroq), xato (C++ exception → Python). Amaliyot — m.def, py::class_, stl.h, yig'ish. pybind11 — mavjud C++ ni Python'ga oson.

2.7. pybind11 vs PyO3/Cython

Jihat pybind11 (C++) PyO3 (Rust) Cython
Til C++ Rust Python-ga o'xshash
Maqsad Mavjud C++ o'rash Yangi tez+xavfsiz O'z kod tezlashtirish
Xavfsizlik C++ (qo'lda) Rust (ownership) O'rta
O'rnatish Header-only Cargo pip
Kuchli tomon C++ ekotizim Xavfsizlik Oson

pybind11 vs PyO3/Cython: pybind11 (C++ — mavjud C++ kutubxona o'rash, C++ ekotizim — OpenCV/Eigen, header-only, lekin C++ xavfsizlik qo'lda), PyO3 (Rust — yangi tez+xavfsiz kengaytma, ownership 30.9), Cython (Python'ga o'xshash — o'z kodni tezlashtirish, eng oson). Tanlov: mavjud C++ (pybind11 — qayta yozishsiz), yangi xavfsiz yadro (Rust/PyO3), o'z Python kodni (Cython). pybind11 kuchi — ulkan C++ ekotizim (o'yinlar, ilmiy, moliya); agar C++ kod/kutubxona bor bo'lsa — pybind11 (o'rash). PyO3 yangi kod uchun (xavfsiz), pybind11 mavjud C++ uchun. pybind11 vs PyO3/Cython — mavjud C++ vs yangi Rust vs o'z Python. Maqsadga qarab.

2.8. pybind11 — C++ ekotizimga ko'prik

pybind11 asosiy g'oyasi — C++ ekotizimga ko'prik: dunyoda ulkan C++ kod bazasi bor (o'yin dvigatellari, OpenCV — kompyuter ko'rish, Eigen — matematika, ilmiy kutubxonalar); pybind11 bularni Python'ga qayta yozishsiz olib keladi (m.def, py::class_ — bir necha qator, avtomatik STL tur). Bu C API (30.5 — qiyin) ning zamonaviy C++ muqobili va PyO3 (30.10 — Rust) ning C++ analogi. pybind11 mavjud C++ mehnatini saqlaydi (yillar kodi qayta yozilmaydi — o'raladi). Bu 30.1 (to'g'ri til to'g'ri ishga — C++ yadro + Python interfeys) ning C++ amalga oshirilishi; TensorFlow, PyTorch, SciPy qismlari pybind11 bilan. Agar C++ kod/kutubxona mavjud — pybind11 ideal (o'rash, qayta yozishsiz). pybind11 — mavjud C++ ni Python'ga. Ekotizim ko'prigi. Qayta yozishsiz.


3. Tez ma'lumotnoma

cpp
// PYBIND11 — C++ ni Python'ga (mening_modul.cpp)
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>       // STL avtomatik tur
namespace py = pybind11;

// C++ funksiya (oddiy)
int qoshish(int a, int b) { return a + b; }

// C++ klass
class Nuqta {
public:
    Nuqta(double x, double y) : x(x), y(y) {}
    double masofa() const;
    double x, y;
};

// MODUL
PYBIND11_MODULE(mening_modul, m) {
    // m.def — funksiyani ochish
    m.def("qoshish", &qoshish, "yig'indi");

    // py::class_ — klassni ochish
    py::class_<Nuqta>(m, "Nuqta")
        .def(py::init<double, double>())    // konstruktor
        .def("masofa", &Nuqta::masofa)      // metod
        .def_readwrite("x", &Nuqta::x);     // maydon
}
AVTOMATIK TUR (STL — stl.h):
   int ↔ int · double ↔ float · std::string ↔ str
   std::vector ↔ list · std::map ↔ dict · std::pair ↔ tuple

PYBIND11 vs PYO3 vs CYTHON:
   pybind11 — mavjud C++ o'rash (OpenCV, Eigen)
   PyO3 — yangi tez+xavfsiz (Rust) · Cython — o'z kod

QOIDA: m.def (funksiya) · py::class_ (klass) · stl.h (STL) · header-only

pybind11 xulosasi

pybind11 — C++ ni Python'ga (header-only, oson)
m.def — funksiyani ochish (nom + manzil + hujjat)
py::class_ — C++ klass → Python klass (konstruktor/metod/maydon)
Avtomatik tur (STL — vector↔list, map↔dict) · stl.h
Mavjud C++ o'rash (qayta yozishsiz) · PyO3 (Rust) analogi

4. Batafsil misollar

pybind11 C++ kompilyator talab qiladi; misollar pybind11 struktura mantiqini (deterministik) modellashtiradi.

Misol 1 — m.def (funksiyani ochish)

python
"""m.def: C++ funksiyani Python'ga ochish (model)."""


def m_def(python_nom: str, cpp_funksiya: str, hujjat: str) -> dict:
    return {
        "python_nom": python_nom,
        "cpp_funksiya": cpp_funksiya,
        "hujjat": hujjat,
    }


def main() -> None:
    d = m_def("kvadrat", "&kvadrat", "Sonning kvadrati")

    print("=== 1. m.def argumentlari ===")
    print(f"  python nom: {d['python_nom']}")
    print(f"  C++ funksiya: {d['cpp_funksiya']}")
    print(f"  hujjat: {d['hujjat']}")

    print("\n=== 2. Python'da ko'rinishi ===")
    print(f"  modul.{d['python_nom']}3.0-bob → 9.0")

    print("\n=== 3. Ekvivalentlar ===")
    print("  C: PyMethodDef (qo'lda)")
    print("  PyO3: #[pyfunction] · pybind11: m.def")

    print("\n=== 4. Bir chaqiruv ===")
    print("  m.def(nom, manzil, hujjat) — tayyor")
    print("  ⭐ m.def — funksiyani ochish (avtomatik C API)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. m.def argumentlari ===
  python nom: kvadrat
  C++ funksiya: &kvadrat
  hujjat: Sonning kvadrati

=== 2. Python'da ko'rinishi ===
  modul.kvadrat(3.0) → 9.0

=== 3. Ekvivalentlar ===
  C: PyMethodDef (qo'lda)
  PyO3: #[pyfunction] · pybind11: m.def

=== 4. Bir chaqiruv ===
  m.def(nom, manzil, hujjat) — tayyor
  ⭐ m.def — funksiyani ochish (avtomatik C API)

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

Misol 2 — py::class_ (klass zanjiri)

python
"""py::class_: C++ klass, .def zanjiri (model)."""


class ClassBinding:
    def __init__(self, cpp_nom: str, python_nom: str) -> None:
        self.cpp_nom = cpp_nom
        self.python_nom = python_nom
        self.qismlar = []

    def init(self, imzo: str) -> "ClassBinding":
        self.qismlar.append(f".def(py::init<{imzo}>())")
        return self

    def metod(self, nom: str) -> "ClassBinding":
        self.qismlar.append(f'.def("{nom}", &{self.cpp_nom}::{nom})')
        return self

    def maydon(self, nom: str) -> "ClassBinding":
        self.qismlar.append(f'.def_readwrite("{nom}", ...)')
        return self


def main() -> None:
    b = ClassBinding("Nuqta", "Nuqta")
    b.init("double, double").metod("masofa").maydon("x").maydon("y")

    print("=== 1. Klass binding ===")
    print(f"  py::class_<{b.cpp_nom}>(m, \"{b.python_nom}\")")

    print("\n=== 2. .def zanjiri ===")
    for q in b.qismlar:
        print(f"    {q}")

    print("\n=== 3. Python'da ===")
    print("  n = geo.Nuqta(3, 4); n.masofa(); n.x")

    print("\n=== 4. OOP ===")
    print("  konstruktor + metod + maydon → Python klass")
    print("  ⭐ py::class_ — C++ klass → Python klass")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Klass binding ===
  py::class_<Nuqta>(m, "Nuqta")

=== 2. .def zanjiri ===
    .def(py::init<double, double>())
    .def("masofa", &Nuqta::masofa)
    .def_readwrite("x", ...)
    .def_readwrite("y", ...)

=== 3. Python'da ===
  n = geo.Nuqta(3, 4); n.masofa(); n.x

=== 4. OOP ===
  konstruktor + metod + maydon → Python klass
  ⭐ py::class_ — C++ klass → Python klass

Nima ko'rsatdi: 2.3-bo'lim.

Misol 3 — Avtomatik tur (STL)

python
"""Avtomatik tur: C++ STL ↔ Python konteyner (model)."""


TUR_JADVAL = {
    "int": "int",
    "double": "float",
    "std::string": "str",
    "std::vector<T>": "list",
    "std::map<K,V>": "dict",
    "std::pair<A,B>": "tuple",
}


def main() -> None:
    print("=== 1. Tur jadvali ===")
    for cpp, python in TUR_JADVAL.items():
        print(f"  {cpp:18} ↔ {python}")

    print("\n=== 2. STL uchun ===")
    print("  #include <pybind11/stl.h> (vector, map)")

    print("\n=== 3. Avtomatik ===")
    print("  pybind11 o'zi o'giradi (template)")

    print("\n=== 4. Ekvivalent ===")
    print("  PyO3: Vec↔list · pybind11: std::vector↔list")
    print("  ⭐ Avtomatik tur — C++ STL ↔ Python (stl.h)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Tur jadvali ===
  int                ↔ int
  double             ↔ float
  std::string        ↔ str
  std::vector<T>     ↔ list
  std::map<K,V>      ↔ dict
  std::pair<A,B>     ↔ tuple

=== 2. STL uchun ===
  #include <pybind11/stl.h> (vector, map)

=== 3. Avtomatik ===
  pybind11 o'zi o'giradi (template)

=== 4. Ekvivalent ===
  PyO3: Vec↔list · pybind11: std::vector↔list
  ⭐ Avtomatik tur — C++ STL ↔ Python (stl.h)

Nima ko'rsatdi: 2.4-bo'lim.

Misol 4 — Muqobillar (maqsad)

python
"""Muqobillar: pybind11/PyO3/Cython maqsadi (tanlov modeli)."""


VOSITALAR = {
    "pybind11": "mavjud C++ kutubxona o'rash",
    "PyO3": "yangi tez+xavfsiz kengaytma (Rust)",
    "Cython": "o'z Python kodini tezlashtirish",
}


def tanlov(vaziyat: str) -> str:
    if "C++" in vaziyat:
        return "pybind11"
    elif "xavfsiz" in vaziyat or "yangi" in vaziyat:
        return "PyO3"
    else:
        return "Cython"


def main() -> None:
    print("=== 1. Vositalar ===")
    for nom, maqsad in VOSITALAR.items():
        print(f"  {nom}: {maqsad}")

    print("\n=== 2. Mavjud C++ kutubxona ===")
    print(f"  tanlov: {tanlov('mavjud C++ kutubxona bor')}")

    print("\n=== 3. Yangi xavfsiz yadro ===")
    print(f"  tanlov: {tanlov('yangi xavfsiz yadro')}")

    print("\n=== 4. O'z Python kod ===")
    print(f"  tanlov: {tanlov('o.z python kodni tezlashtirish')}")
    print("  ⭐ Muqobil — maqsadga qarab (pybind11 mavjud C++)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Vositalar ===
  pybind11: mavjud C++ kutubxona o'rash
  PyO3: yangi tez+xavfsiz kengaytma (Rust)
  Cython: o'z Python kodini tezlashtirish

=== 2. Mavjud C++ kutubxona ===
  tanlov: pybind11

=== 3. Yangi xavfsiz yadro ===
  tanlov: PyO3

=== 4. O'z Python kod ===
  tanlov: Cython
  ⭐ Muqobil — maqsadga qarab (pybind11 mavjud C++)

Nima ko'rsatdi: 2.7-bo'lim.


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

Noto'g'ri fikr To'g'risi
"pybind11 = C API qiyinligi" pybind11 oson (m.def)
"STL avtomatik (har doim)" stl.h kerak (vector, map)
"pybind11 kutubxona bog'lash" Header-only (faqat sarlavha)
"Faqat funksiya" py::class_ (klass ham)
"pybind11 = PyO3" pybind11 C++, PyO3 Rust
"C++ o'rniga qayta yoz" pybind11 o'raydi (mavjud C++)
"Turlarni qo'lda o'gir" Avtomatik (C++ ↔ Python)
"C++ kompilyatorsiz" C++ kompilyator kerak

6. Keng tarqalgan xatolar va yechimlari

1. STL uchun stl.h unutish

cpp
// std::vector argument, stl.h yo'q (o'girmaydi)              // ⚠️
#include <pybind11/stl.h>   // STL o'girish                    // ✅

2. m.def da & unutish

cpp
m.def("f", qoshish);   // manzil emas (xato)                  // ⚠️
m.def("f", &qoshish);   // & (funksiya manzili)                // ✅

3. Konstruktor unutish (py::class_)

cpp
py::class_<Nuqta>(m, "Nuqta");   // init yo'q (yaratib bo'lmaydi)  // ⚠️
.def(py::init<double, double>())   // konstruktor              // ✅

4. C++ exception boshqarmaslik

cpp
// C++ throw (pybind11 o'giradi, lekin tekshir)               // ⚠️
// pybind11 std::exception → Python istisno (avtomatik)        // ✅

5. Mavjud C++ ni qayta yozish

python
# katta C++ kutubxonani Python'da qayta yozish (behuda)       # ⚠️
# pybind11 (o'rash — qayta yozishsiz)                          # ✅

6. Yig'ishsiz import

python
import mening_modul   # .cpp yig'ilmagan                      # ⚠️
# setup.py (pybind11) yoki CMake (yig')                        # ✅

7. Xato maqsad (Cython o'rniga pybind11)

python
# o'z Python kodni pybind11 bilan (C++ yozish kerak)          # ⚠️
# o'z kod → Cython (Python'ga o'xshash)                        # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 30.10-dars (o'tilgan): PyO3 — Rust ekvivalenti
  • 30.5-dars (o'tilgan): C API — pybind11 yashiradi
  • 30.7-dars (o'tilgan): Cython — o'z kod muqobili
  • 30.1-dars (o'tilgan): To'g'ri til to'g'ri ishga
  • 29.2-dars (o'tilgan): Bottleneck — C++ tezlik

8. Eng yaxshi amaliyotlar

  1. m.def (funksiya), py::class_ (klass).

  2. stl.h (STL avtomatik tur — vector, map).

  3. & (funksiya manzili — m.def).

  4. Konstruktor (py::init — klass).

  5. Header-only (faqat sarlavha — oddiy).

  6. Mavjud C++ o'rash (qayta yozishsiz).

  7. pybind11 mavjud C++, PyO3 yangi xavfsiz.

  8. O'z kod → Cython (pybind11 emas).


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # pybind11 nima?
2.  # pybind11 nega oson?
3.  # m.def nima?
4.  # m.def argumentlari?
5.  # py::class_ nima?
6.  # py::init nima?
7.  # avtomatik tur nima?
8.  # std::vector ↔ ?
9.  # STL uchun nima kerak?
10. # header-only nima?
11. # pybind11 vs PyO3?
12. # qachon pybind11?
Javoblar
  1. C++ ni Python'ga bog'lash kutubxonasi
  2. Zamonaviy C++ (C API yashirin)
  3. C++ funksiyani Python'ga ochish
  4. Nom, C++ manzil (&), hujjat
  5. C++ klassni Python klass'ga
  6. Konstruktor (py::class_ ichida)
  7. C++ ↔ Python turlar (avtomatik)
  8. list
  9. #include <pybind11/stl.h>
  10. Faqat sarlavha (bog'lashsiz)
  11. pybind11 C++, PyO3 Rust
  12. Mavjud C++ kutubxona o'rash

Vazifa 2: Xatolarni tuzating

cpp
1.  // std::vector, stl.h yo'q

2.  m.def("f", qoshish);   // & yo'q

3.  py::class_<Nuqta>(m, "Nuqta");   // init yo'q

4.  // katta C++ ni qayta yozish

5.  // o'z Python kodni pybind11
Javoblar
cpp
1.  #include <pybind11/stl.h>

2.  m.def("f", &qoshish);

3.  .def(py::init<...>())

4.  pybind11 (o'rash)

5.  Cython (o'z kod)

Vazifa 3: m.def

Modellang:

  1. Nom
  2. Manzil
  3. Hujjat
  4. Ekvivalent

Vazifa 4: py::class_

Modellang:

  1. Klass
  2. Konstruktor
  3. Metod
  4. Maydon

Vazifa 5: Avtomatik tur

Modellang:

  1. int
  2. std::vector
  3. STL
  4. stl.h

Vazifa 6: Muqobil

Modellang:

  1. pybind11
  2. PyO3
  3. Cython
  4. Maqsad

Vazifa 7: O'ylash

pybind11 mavjud C++ kod bazasini (yillar mehnati — OpenCV, Eigen) Python'ga qayta yozishsiz olib keladi. Nima uchun "mavjud kodni o'rash" (qayta yozishdan ko'ra) ko'pincha to'g'ri qaror, va nega "qayta yozish vasvasasi" (rewrite) muhandislikda ko'pincha xato — mavjud, sinovdan o'tgan kodning "yashirin qiymati" nimada?

Javob

Qisqa javob: "Mavjud kodni o'rash" ko'pincha to'g'ri qaror, chunki: mavjud kod (ayniqsa yillar ishlatilgani — OpenCV, Eigen) yashirin qiymatga ega — u shunchaki kod emas, balki yillar davomida topilgan va tuzatilgan xatolar, chekka holatlar, optimallashtirishlar to'plami (har bir bug-fix — real muammodan saboq); qayta yozish bularni yo'qotadi (nolldan boshlaydi — o'sha xatolarni qaytadan qiladi). O'rash (pybind11) mavjud qiymatni saqlaydi (kod o'zgarmaydi — faqat interfeys qo'shiladi), qayta yozish uni tashlaydi. "Nega qayta yozish vasvasasi xato": (1) yashirin qiymat yo'qoladi — mavjud kod "chirkin" ko'rinishi mumkin, lekin har satr sabab bilan (bug-fix, chekka holat); qayta yozish bu bilimni yo'qotadi (Chesterton to'sig'i — nega borligini bilmasdan olib tashlash); (2) xatolar qaytadan — yangi kod yangi xatolar (eski kod ularni yillar oldin hal qilgan); "ikkinchi tizim sindromi" (rewrite ko'pincha vaqt/byudjetdan oshadi, yomonroq chiqadi); (3) vaqt/xarajat — qayta yozish yillar (mavjud kod tayyor); (4) risk — ishlaydigan tizimni buzish (mavjud ishlaydi, yangi noma'lum). "Yashirin qiymat" — mavjud kodda kodlangan domen bilimi (real dunyo murakkabligini boshqarish — chekka holatlar, xato tuzatishlar, unumdorlik sozlamalari) — bu kodga qaraganda ko'rinmaydi, lekin bebaho. Istisno: qayta yozish ba'zan to'g'ri (kod chindan tuzatib bo'lmas, texnologiya eskirgan, talablar tubdan o'zgargan) — lekin bu kam (odatda o'rash/refactor afzal). Bu umumiy muhandislik donoligi: mavjud, ishlaydigan, sinovdan o'tgan kodni qadrla (yashirin qiymat); o'rash/refactor (bosqichma-bosqich) qayta yozishdan (nolldan) afzal; Chesterton to'sig'i (nega borligini bilmasdan olib tashlama). Muhandislik saboqlari: mavjud kodda yashirin qiymat (yillar bug-fix, chekka holat, domen bilim); qayta yozish uni yo'qotadi (xatolar qaytadan, ikkinchi tizim sindromi); o'rash (pybind11) qiymatni saqlaydi (interfeys qo'shadi, kod o'zgarmaydi); qayta yozish kam holatda to'g'ri (odatda o'rash/refactor). pybind11 misolida: OpenCV/Eigen (yillar mehnat) o'raladi (Python interfeys), qayta yozilmaydi (qiymat saqlanadi).

1. Nega o'rash to'g'ri qaror

  • Mavjud kod — yashirin qiymat (yillar bug-fix, chekka holat)
  • O'rash saqlaydi (kod o'zgarmaydi, interfeys qo'shiladi)
  • Qayta yozish tashlaydi (nolldan)

2. Nega qayta yozish vasvasasi xato

  • Yashirin qiymat yo'qoladi (Chesterton to'sig'i)
  • Xatolar qaytadan (ikkinchi tizim sindromi)
  • Vaqt/xarajat (yillar) + risk (buzish)

3. Yashirin qiymat nimada

Ko'rinadigan Yashirin
Kod satrlari Yillar bug-fix
Funksiyalar Chekka holatlar
Struktura Domen bilim

4. Istisno (qayta yozish to'g'ri)

Kam holatda: tuzatib bo'lmas, texnologiya eskirgan, talablar tubdan o'zgargan. Odatda o'rash/refactor afzal.

5. Muhandislik saboqlari

  1. Mavjud kodda yashirin qiymat (bug-fix, domen)
  2. Qayta yozish yo'qotadi (xatolar qaytadan)
  3. O'rash saqlaydi (interfeys, kod o'zgarmaydi)
  4. Chesterton to'sig'i (bilmasdan olib tashlama)

6. Xulosa

  1. Mavjud kod — yashirin qiymat (yillar mehnat)
  2. Qayta yozish uni yo'qotadi (vasvasa — xato)
  3. pybind11 — o'rash (qiymat saqlanadi)
  4. Qayta yozish kam holatda to'g'ri

Nimani mustahkamlaydi: 2.1, 2.8-bo'limlar.


Xulosa

Bu darsda C++ va pybind11 ni o'rgandik.

Eng muhim uch fikr:

  1. pybind11 va m.def. pybind11 — C++ va Python o'rtasida bog'lovchi header-only kutubxona (faqat sarlavha — o'rnatish oson): C++ kodini Python'dan import qilinadigan qiladi, minimal kod bilan (m.def, PYBIND11_MODULE), C API murakkabligini yashirib; PyO3 (30.10 — Rust) ning C++ ekvivalenti. m.def — C++ funksiyani Python'ga ochadi (m.def("nom", &funksiya, "hujjat") — Python nomi, C++ manzil &, docstring); PyMethodDef 30.6-bob va #[pyfunction] 30.10-bob ekvivalenti.

  2. py::class_ va avtomatik tur. py::class_ — C++ klassni Python klass'ga: py::class_<Klass>(m, "Nom"), keyin .def(py::init<...>()) (konstruktor), .def("metod", &Klass::metod) (metod), .def_readwrite (maydon); PyO3 #[pyclass] ekvivalenti (OOP). Avtomatik tur (STL) — pybind11 C++ turlarini Python'ga o'giradi: asosiy (int↔int, double↔float, std::string↔str) va STL (std::vector↔list, std::map↔dict — #include <pybind11/stl.h> bilan). Header-only — faqat sarlavha (kutubxona bog'lashsiz, pip install pybind11).

  3. Muqobil va C++ ekotizimga ko'prik. pybind11 vs PyO3/Cython: pybind11 (C++ — mavjud C++ kutubxona o'rash, OpenCV/Eigen ekotizim), PyO3 (Rust — yangi tez+xavfsiz), Cython (o'z Python kodni); tanlov maqsadga qarab (mavjud C++ → pybind11, yangi xavfsiz → PyO3, o'z kod → Cython). pybind11 — C++ ekotizimga ko'prik (ulkan C++ kod bazasini — o'yin, ilmiy, moliya — Python'ga qayta yozishsiz); TensorFlow, PyTorch, SciPy qismlari pybind11 bilan. Mavjud kodni o'rash (qayta yozishdan) ko'pincha to'g'ri — mavjud kodning yashirin qiymati (yillar bug-fix, chekka holat, domen bilim); qayta yozish vasvasasi xato (Chesterton to'sig'i, ikkinchi tizim sindromi).

Keyingi darsda Go va gRPC ni o'rganamiz: Go tili (Google'ning parallel dasturlash tili) va gRPC (yuqori unumdor xizmatlararo aloqa) — mikroservislarda Python va Go'ni birga ishlatish.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
30.12-dars: C++ va pybind11 — IlmHamroh