Leksiya 7 · 2-qism
Polimorfizm, inkapsulyatsiya va uzilishlarga chidamli bank tizimlarini loyihalash
Bugun biz moslashuvchan va himoyalangan arxitekturalarni qanday loyihalashni koʻrib chiqamiz. Fintex sohasidan olingan haqiqiy misollarda - murakkab maʼlumotlar oqimini qanday boshqarish, parollarni loglarga tushishdan himoya qilish va oʻnlab toʻlov shlyuzlarini yagona interfeys orqali ishini tashkil etish.
6-leksiya takrori
Oʻtgan darsda biz poydevorni qoʻydik: holat va xatti-harakatni klasslarga joylashni oʻrgandik, hamda vorislik bilan tanishdik.
Murakkabroq tushunchalarga - dinamik polimorfizm va inkapsulyatsiyaga - oʻtishdan oldin terminologiyani bazaviy misollarda mustahkamlab olish zarur. Bu poydevorsiz MRO va Name Mangling mexanizmlarida osongina chalkashib ketish mumkin.
Takror
Bank hisoblarini yuritish misolida maʼlumotlarni boshqarishning ikki yondashuvini solishtiramiz.
Klass - moliyaviy holat va u bilan ishlash mantigʻini yagona tuzilmaga bogʻlovchi foydalanuvchi maʼlumot turi.
Takror
Tuzilmaning dasturiy tavsifi. Oʻzi mijozning aniq maʼlumotlarini saqlamaydi va maʼlumot uchun xotira egallamaydi.
Xotiradagi aniq obyekt - masalan, haqiqiy balansga ega mijoz hisobi. Bitta klassdan millionlab izolyatsiyalangan obyektlar yaratiladi.
Takror
Obyekt ichidagi, uning joriy holatini aks ettiruvchi oʻzgaruvchilar: account_number, currency, is_blocked.
Klass ichidagi, obyekt holatiga kirish huquqiga ega funksiyalar: withdraw(), block_account().
💡 Yaxshi loyihalangan klass oʻz atributlarini mustaqil boshqaradi, tashqi kod esa u bilan faqat metod chaqiruvlari orqali muloqot qiladi.
Takror
__init__ metodi va self argumenti__init__ - obyekt konstruktori, xotira ajratilgandan soʻng avtomatik chaqiriladi. self - joriy nusxaga oshkora havola.
Kontekst
self vs Java thisself har bir metodning birinchi argumenti sifatida yoziladi. "Oshkora yashirinidan yaxshiroq".
JVM havolani avtomatik uzatadi, ichida esa u this orqali mavjud boʻladi.
Takror
Takror
__str__ metodiTakror
Takror
super()Takror
Python bilan ishlaganda siz OOP dan har daqiqada foydalanasiz - nuqta orqali deyarli har bir chaqiruv - bu obyekt metodi.
Takror
| Tushuncha | Qisqacha | Arxitekturadagi maʼnosi |
|---|---|---|
| Klass / Nusxa | Tuzilma tavsifi vs RAMdagi obyekt | Mahsulot shabloni va mijozning haqiqiy hisobi |
| Atribut / Metod | Holat oʻzgaruvchisi vs funksiya | Balans (maʼlumot) va oʻtkazma metodi (xatti-harakat) |
| __init__ / self | Konstruktor va kontekstga havola | Yaratishdagi kirish nuqtasi va nusxaga havola |
| Vorislik / super() | Nusxa-koʻchirmasdan kengaytirish | BasicAccount asosida CreditAccount |
Kurs xaritasi
| Tushuncha | Holat | Bosqich |
|---|---|---|
| Vorislik | 🟢 OʻRGANILDI | Klasslarni kengaytirish sintaksisi va super(). |
| Polimorfizm | 🟡 JORIY MAVZU | Turli toʻlov shlyuzlari uchun yagona interfeys. |
| Inkapsulyatsiya | ⚪ KUTILMOQDA | Kritik maʼlumotlarni yashirish va validatsiya. |
| Abstraksiya | ⚪ KUTILMOQDA | Biznes-mantiqni amalga oshirish tafsilotlaridan ajratish. |
Bugun
_ va __ modifikatorlari, @property, setterlar@staticmethod, @classmethod+, ==, len() operatorlariPolimorfizm
Kassadagi toʻlov terminalini tasavvur qiling. Unga mijoz aynan nimani yaqinlashtirishi farqsiz: UzCard plastik kartasi, Humo Pay'li smartfon yoki Milly Bank'dan QR-kod. Terminal uchun bitta interfeys mavjud - "toʻlovni qabul qilish". Yechib olish aynan qanday roʻy berishi esa aniq toʻlov vositasiga bogʻliq.
Polimorfizm - dasturning turli obyektlar bilan yagona interfeys orqali, faqat metod nomiga tayanib, obyektning ichki tuzilishiga emas, muloqot qila olish qobiliyati.
Polimorfizm
Vorislik va qayta aniqlash orqali. Ota-klass yaratiladi; vorislar bir xil nomli, ammo oʻz mantigʻiga ega metodni amalga oshiradi.
Duck typing. Vorislik talab qilinmaydi: mustaqil klasslarda bir xil nomli metod boʻlsa, uni polimorf tarzda chaqirish mumkin.
Polimorfizm
Klassik polimorfizm
Qayta aniqlash - bu voris-klass ota-klassdagi bilan bir xil nomli metodni eʼlon qilib, uni oʻzicha amalga oshirishidir.
obj.greet() chaqirilganda Python metodni obyektning oʻz klassidan boshlab qidiradi. Vorisdagi versiya ota-klassnikini "yopadi". super().greet() esa qoʻshimcha ravishda ota-klass versiyasini ham bajarishga imkon beradi.
Klassik polimorfizm
Ota-klass umumiy mantiqni saqlaydi. Voris-klass metodni qayta aniqlaydi:
super() ota-klass versiyasini chaqiradi. UzCardGateway umumiy yadro mantigʻini yoʻqotmasdan oʻz xatti-harakatini qoʻshadi.
Klassik polimorfizm
Humo va Milly Bank metodni xuddi shunday qayta aniqlaydi. run_checkout istalgan shlyuz bilan ishlaydi:
Metodlarni qayta aniqlash
Har bir shlyuz process_payment ni oʻzicha qayta aniqlaydi. super() avval umumiy yadro mantigʻini (logga yozish), soʻngra - aniq shlyuz kodini bajaradi. run_checkout funksiyasi yagona metodni chaqiradi va unga qaysi klass uzatilganini bilmaydi.
Qayta aniqlashni mustahkamlaymiz
Uch tarif calculate_fee ni oʻz formulasi bilan qayta aniqlaydi. Sikl xuddi shu metodni chaqiradi - Python obyekt turiga qarab kerakli amalga oshirilishni oʻzi qoʻyadi.
Boshqa tillarda
| Mezon | Python | Java |
|---|---|---|
| Standart rejim | Barcha metodlar virtual. Vorisdagi nom mosligi ota-klass metodini qayta aniqlaydi. | Signaturalarning mosligini talab qiladi. @Override annotatsiyasi tavsiya etiladi. |
| Turlarni nazorat qilish | Runtime darajasida yoʻq. | Kompilyator nazorat qiladi. |
| Qidiruv tamoyili | Bajarilish payti MRO boʻylab dinamik qidiruv. | Kompilyatsiya bosqichida virtual metodlar jadvali (VMT) boʻylab. |
Qayta aniqlash xavfi
Sababi: format_inn None qaytardi, None.upper() chaqiruvi esa xato bilan tugadi - NoneType turida bu metod yoʻq.
Qayta aniqlash xavfi
Kompilyatsiya qilinadigan tillarda bunday xato yigʻish (build) xatosini chaqirardi. Python esa indamay yangi metod yaratadi va ota-klassnikini chaqiradi.
Turlar ierarxiyasi
object nimaobject - bu Python butun turlar tizimining poydevori sifatida oʻzi yaratgan oʻrnatilgan klass. U sizning kodingizdan ham oldin mavjud: uni na aniqlash, na import qilish kerak.
Pythondagi istalgan klass - oxir-oqibat object vorisi. Aynan undan barcha obyektlar bazaviy imkoniyatlarni oladi: __init__, __str__, __eq__, __hash__ va boshqalar.
Turlar ierarxiyasi
object ni avtomatik qoʻyadiSiz ota-klassni koʻrsatmasdan klass yozsangiz, Python indamay object ni ota-klass sifatida qoʻshadi. Quyidagi ikki yozuv toʻliq bir xil:
object bilan qavslarni yozmaslik mumkin - Python uni oʻzi qoʻyadi. Shu sababli biz kodda ota-klassni "koʻrmaymiz", ammo u doimo oʻsha yerda.
Turlar ierarxiyasi
object dan nimani oladiAgar ota-klass oshkora koʻrsatilmasa, Python object dan voris qiladi - butun ierarxiyaning choʻqqisidan.
Boshqa tillarda
object vs Java java.lang.Object| Parametr | Python | Java |
|---|---|---|
| Avto-bogʻlanish | Istalgan foydalanuvchi ierarxiyasini yopadi. | Obyekt modelining mutlaq ildizi. |
| Bazaviy toʻplam | __new__, __init__, __repr__, __eq__. | toString(), equals(), hashCode(). |
| Koʻp vorislik | MROning yakuniy nuqtasi. | Qoʻllanilmaydi - Java faqat yagona vorislikni qoʻllaydi. |
Ierarxiyalar ziddiyati
Chuqur tahlil
Python C3-linearizatsiyadan foydalanadi: metod chaqirilganda klasslar MRO tartibida koʻrib chiqiladi, birinchi topilgani bajariladi.
Kooperativ vorislik
super() va MROsuper() metodni "eʼlondagi ota-klass" da emas, joriy obyektning MRO zanjiridagi keyingi klassda chaqiradi.
Left ichidagi super() boshqaruvni Right ga uzatdi, garchi ular bevosita bogʻliq boʻlmasa ham - bu kooperativ koʻp vorislik.
Ierarxiyalar ziddiyati
Polimorfizm
Polimorfizm
Yagona interfeys turli xil obyektlar toʻplamini oddiy sikllarda - if isinstance() orqali tur tekshiruvlarisiz - qayta ishlashga imkon beradi.
Arxitektura
Arxitektura nuqtai nazaridan polimorfizm biznes-mantiqni aniq vendorlarning texnik tafsilotlaridan izolyatsiya qiladi.
Yangi shlyuz (masalan, Click yoki Payme) ulanganda yadro kodini oʻzgartirish talab qilinmaydi. PaymentGateway voris klassini yaratish va process_payment ni amalga oshirish kifoya. Qolgani avtomatik ishlaydi.
Yakunlar
| Qoida | Nega muhim |
|---|---|
| Metod nomini aniq saqlang | Xato yangi metod yaratadi, eskisi esa indamay ishlashda davom etadi |
| Qaytariladigan turni saqlang | Ota-klass kodi aniq maʼlumot turini olishni kutadi |
| Kerak boʻlsa super() ni chaqiring | Agar bazaviy mantiq (audit-log) bajarilishi shart boʻlsa |
| Argumentlar signaturasini saqlang | Aks holda polimorf chaqiruv kutilmagan maʼlumot oladi |
Dinamik polimorfizm
"Agar obyekt oʻrdakdek tutsa - u oʻrdakdir". Umumiy ajdodlar shart emas: kerakli nomli metod boʻlsa - uni chaqirish mumkin.
Diqqat
OOP haqiqiy loyihalarda
Scikit-learn toʻliq duck typing ustiga qurilgan: .fit() va .predict() metodlariga ega istalgan model umumiy payplaynda ishlaydi.
Yakunlar
| Xususiyat | Qayta aniqlash | Duck typing |
|---|---|---|
| Umumiy ajdod talab qiladi | Ha | Yoʻq |
| Kontrakt nazorati | Ierarxiya orqali | Faqat metod nomi boʻyicha |
| Xatolar qachon koʻrinadi | Loyihalash bosqichida | Faqat runtimeda |
| Qayerda qoʻllaniladi | Bitta tizim shlyuzlari | Mustaqil kutubxonalar |
Kurs xaritasi
| Tushuncha | Holat | Tavsif |
|---|---|---|
| Vorislik | 🟢 OʻRGANILDI | Klasslarni kengaytirish sintaksisi va super(). |
| Polimorfizm | 🟢 OʻRGANILDI | Qayta aniqlash, MRO va duck typing. |
| Inkapsulyatsiya | 🟡 JORIY MAVZU | Kritik maydonlarni tashqi kirishdan yashirish. |
| Abstraksiya | ⚪ KUTILMOQDA | Biznes-mantiqni amalga oshirish tafsilotlaridan ajratish. |
Inkapsulyatsiya
Ochiq koʻrinishdagi, har kimga oʻqish va yozish uchun ochiq parol - sizib chiqishga toʻgʻridan-toʻgʻri yoʻl.
Inkapsulyatsiya
Inkapsulyatsiya ikki vazifani hal qiladi:
🔐 Balans yoki parolni toʻgʻridan-toʻgʻri oʻzgartirib boʻlmaydi. Buning uchun change_password() (eski parolni tekshirish va xeshlash bilan) va deposit() (summani validatsiya qilish bilan) metodlari taqdim etiladi.
Boshqa tillarda
private modifikatori kirishni kompilyatsiya darajasida bloklaydi. Tashqaridan user.password ga murojaat - kompilyator xatosi.
Jismoniy cheklovlar yoʻq. Himoya atributlarni nomlash (_ va __) ustiga quriladi. Dasturchilar ularga kelishuv asosida amal qiladi.
Inkapsulyatsiya
_Bitta tag chizigʻi - signal: "maydon ichki, klassdan tashqarida foydalanish uchun moʻljallanmagan".
from module import * da eksport qilinmaydiInkapsulyatsiya
__ va Name ManglingIkkita tag chizigʻi Name Mangling ni yoqadi: __password_hash _KlassNomi__password_hash ga aylanadi. Bu maydonni vorislikda tasodifan qayta aniqlanishidan himoya qiladi.
Inkapsulyatsiya
@property dekoratori - getterlarAgar maʼlumotni oʻqish, ammo jarayonni nazorat qilish yoki chiqishni niqoblash kerak boʻlsa - @property ishlatiladi. U metodni "virtual atribut" ga aylantiradi - murojaat qavslarsiz.
@property nima uchun
@property nima uchun
@property nima uchun
Agar atribut ochiq boʻlgan, soʻngra oʻqishda mantiq talab qilingan boʻlsa - @property uni chaqiruv sintaksisini oʻzgartirmasdan qoʻshishga imkon beradi. Butun tashqi kod ishlashda davom etadi.
Shu sababli Pythonda oddiy atributdan boshlaydi va uni mantiq paydo boʻlgandagina @property ga aylantiradi.
Boshqa tillarda
Har bir maydon birinchi kundan getBalance() / setBalance() ga oʻraladi, ichida mantiq boʻlmasa ham. Katta hajmdagi shablon kod.
Oddiy atributdan boshlaymiz. Zarurat boʻlganda @property ga aylantiramiz - va butun tashqi kod oʻzgarishlarsiz ishlashda davom etadi.
Inkapsulyatsiya
@property.setter - yozishdagi validatsiyaSetter = orqali qiymat berishni ushlab qoladi va maʼlumotni saqlashdan oldin tekshiradi.
Ichki mexanizm
@property + setter bogʻlanishi qanday ishlaydiGetter va setter nomlari mos kelishi shart - shuning uchun dekorator @limit.setter deb yoziladi, shunchaki @setter emas.
Inkapsulyatsiya
Inkapsulyatsiya
Konstruktor, himoyalangan balans va tekshiruv bilan hisobni toʻldirish:
Balans toʻgʻridan-toʻgʻri yozishdan yopiq: @property orqali oʻqiladi, faqat metodlar orqali oʻzgartiriladi.
Inkapsulyatsiya
Xuddi shu klass - ikki tomonlama tekshiruvga ega yechish metodi:
Metod summa va qoldiqni oʻzi tekshiradi - notoʻgʻri operatsiya shunchaki oʻtmaydi.
Inkapsulyatsiya
Inkapsulyatsiya
| Vosita | Nima qiladi | Qachon ishlatish kerak |
|---|---|---|
| _name | Ichki tegishlilik haqida signal | Tashqi foydalanish uchun moʻljallanmagan maydonlar |
| __name | Name Mangling - maydonni xotirada qayta nomlaydi | Kritik maʼlumotlar: parollar, tokenlar, PIN-kodlar |
| @property | Nazorat ostida oʻqish | Oʻqishdagi mantiq, niqoblash, hisoblanadigan qiymatlar |
| @name.setter | Yozishdan oldin validatsiya | Saqlashdan oldin maʼlumotni tekshirish |
| @property settersiz | Faqat oʻqish uchun | Oʻzgarmas identifikatorlar: shartnoma ID si, hisob raqami |
Yakunlar
| Tushuncha | Holat | Qaysi muammoni hal qiladi | Asosiy vositalar |
|---|---|---|---|
| Vorislik | 🟢 | Oʻxshash klasslarda kod takrorlanishi | class Child(Parent), super() |
| Polimorfizm | 🟢 | Kodning aniq amalga oshirilishlarga bogʻliqligi | Qayta aniqlash, Duck Typing, MRO |
| Inkapsulyatsiya | 🟢 | Maʼlumotga toʻgʻridan-toʻgʻri kirish mantiqni buzadi | _, __, @property, setter |
| Abstraksiya | ⚪ | Yuqori darajadagi kod tafsilotlar bilan aralashgan | ABC, @abstractmethod |
Klass darajasi
Nusxa atributi self.maydon orqali har bir obyekt uchun alohida yaratiladi. Klass atributi klass tanasida eʼlon qilinadi - barcha nusxalar uchun bitta nusxa.
Klass darajasi
Nusxa orqali oʻzgartirilganda (contract1.base_interest_rate = 0.25) Python shu nusxada yangi atribut yaratadi - klass atributi oʻzgarmasdan qoladi.
Amaliyot
Maʼruzaning birinchi qismi uchun ikkita Jupyter daftari.
Jupyter Notebook, JupyterLab yoki VS Code da oching.