12. Obyektga yo‘naltirilgan dasturlash¶
Obyektga yo‘naltirilgan dasturlash — dasturdagi ma’lumot va ular bilan ishlaydigan funksiyalarni obyektlar atrofida tashkil qilish usulidir.
Python'da obyektga yo‘naltirilgan dasturlashning asosiy tushunchalari:
class
obyekt
atribut
metod
__init__
self
meros olish
polimorfizm
inkapsulyatsiya
Class nima?¶
class obyektlar uchun andoza hisoblanadi.
Masalan, foydalanuvchi uchun class yaratamiz:
class Foydalanuvchi:
pass
Bu hali hech qanday xususiyatga ega emas.
Undan obyekt yaratish mumkin:
foydalanuvchi = Foydalanuvchi()
print(
foydalanuvchi
)
Obyekt nima?¶
Class — andoza.
Obyekt — shu andoza asosida yaratilgan aniq nusxa.
class Foydalanuvchi:
pass
birinchi_foydalanuvchi = (
Foydalanuvchi()
)
ikkinchi_foydalanuvchi = (
Foydalanuvchi()
)
Bu yerda ikkita alohida obyekt mavjud:
Foydalanuvchi
↓
birinchi_foydalanuvchi
Foydalanuvchi
↓
ikkinchi_foydalanuvchi
Atribut¶
Obyektning ma’lumotlari atribut deyiladi.
class Foydalanuvchi:
pass
foydalanuvchi = Foydalanuvchi()
foydalanuvchi.ism = (
"Softromeda"
)
foydalanuvchi.yosh = 25
print(
foydalanuvchi.ism
)
print(
foydalanuvchi.yosh
)
Natija:
Softromeda
25
__init__¶
Obyekt yaratilganida avtomatik bajariladigan maxsus metod __init__ deyiladi.
class Foydalanuvchi:
def __init__(
self,
ism,
yosh
):
self.ism = ism
self.yosh = yosh
Obyekt yaratish:
foydalanuvchi = Foydalanuvchi(
"Softromeda",
25
)
print(
foydalanuvchi.ism
)
print(
foydalanuvchi.yosh
)
self¶
self joriy obyektni bildiradi.
class Foydalanuvchi:
def __init__(
self,
ism,
yosh
):
self.ism = ism
self.yosh = yosh
Bu yerda:
self.ism
↓
joriy obyektning ismi
self.yosh
↓
joriy obyektning yoshi
Masalan:
birinchi_foydalanuvchi = Foydalanuvchi(
"Ali",
25
)
ikkinchi_foydalanuvchi = Foydalanuvchi(
"Vali",
30
)
Har bir obyekt o‘zining qiymatlarini saqlaydi.
Metod¶
Class ichidagi funksiya metod deyiladi.
class Foydalanuvchi:
def __init__(
self,
ism
):
self.ism = ism
def salomlash(
self
):
print(
f"Salom, {self.ism}!"
)
Foydalanish:
foydalanuvchi = Foydalanuvchi(
"Softromeda"
)
foydalanuvchi.salomlash()
Natija:
Salom, Softromeda!
Metodga parametr berish¶
class Hisob:
def __init__(
self,
egasi
):
self.egasi = egasi
self.balans = 0
def pul_qoshish(
self,
miqdor
):
self.balans += miqdor
def balansni_korsatish(
self
):
print(
f"Balans: {self.balans}"
)
Foydalanish:
hisob = Hisob(
"Softromeda"
)
hisob.pul_qoshish(
100000
)
hisob.balansni_korsatish()
Natija:
Balans: 100000
Bir nechta obyekt¶
Bitta class asosida istalgancha obyekt yaratish mumkin.
class Foydalanuvchi:
def __init__(
self,
ism,
yosh
):
self.ism = ism
self.yosh = yosh
def malumot_korsatish(
self
):
print(
f"Ism: {self.ism}"
)
print(
f"Yosh: {self.yosh}"
)
birinchi_foydalanuvchi = Foydalanuvchi(
"Ali",
25
)
ikkinchi_foydalanuvchi = Foydalanuvchi(
"Vali",
30
)
birinchi_foydalanuvchi.malumot_korsatish()
ikkinchi_foydalanuvchi.malumot_korsatish()
Class atributi¶
Ba’zi ma’lumotlar barcha obyektlar uchun umumiy bo‘lishi mumkin.
Bunday ma’lumotni class atributi sifatida yaratish mumkin.
class Foydalanuvchi:
platforma_nomi = "Softromeda"
def __init__(
self,
ism
):
self.ism = ism
Foydalanish:
birinchi_foydalanuvchi = Foydalanuvchi(
"Ali"
)
ikkinchi_foydalanuvchi = Foydalanuvchi(
"Vali"
)
print(
birinchi_foydalanuvchi.platforma_nomi
)
print(
ikkinchi_foydalanuvchi.platforma_nomi
)
Ikkalasida ham:
Softromeda
chiqadi.
Instance atribut va class atribut¶
Quyidagi:
self.ism
obyektga tegishli.
Quyidagi:
platforma_nomi
esa classga tegishli.
class Foydalanuvchi:
platforma_nomi = "Softromeda"
def __init__(
self,
ism
):
self.ism = ism
Class metod¶
@classmethod classning o‘zi bilan ishlaydigan metod yaratadi.
class Foydalanuvchi:
platforma_nomi = "Softromeda"
def __init__(
self,
ism
):
self.ism = ism
@classmethod
def platformani_korsatish(
cls
):
print(
cls.platforma_nomi
)
Foydalanish:
Foydalanuvchi.platformani_korsatish()
Natija:
Softromeda
Bu yerda cls classning o‘zini bildiradi.
Statik metod¶
@staticmethod obyekt yoki classning avtomatik parametrini talab qilmaydi.
class Hisoblagich:
@staticmethod
def qoshish(
birinchi_son,
ikkinchi_son
):
return (
birinchi_son
+ ikkinchi_son
)
Foydalanish:
natija = Hisoblagich.qoshish(
10,
20
)
print(
natija
)
Natija:
30
Oddiy metod, class metod va statik metod¶
Ularning farqi:
oddiy metod
→ self
class metod
→ cls
statik metod
→ self yoki cls kerak emas
Meros olish¶
Bir class boshqa classning xususiyat va metodlarini meros qilib olishi mumkin.
class Inson:
def __init__(
self,
ism
):
self.ism = ism
def salomlash(
self
):
print(
f"Salom, {self.ism}!"
)
class Dasturchi(
Inson
):
pass
Endi:
dasturchi = Dasturchi(
"Softromeda"
)
dasturchi.salomlash()
Natija:
Salom, Softromeda!
Dasturchi Insondan meros oldi.
Ota class va bola class¶
Terminlar:
ota class
parent class
base class
superclass
va:
bola class
child class
subclass
Masalan:
class Inson:
pass
class Dasturchi(
Inson
):
pass
Bu yerda:
Inson
↓
Dasturchi
Meros bilan __init__¶
class Inson:
def __init__(
self,
ism
):
self.ism = ism
class Dasturchi(
Inson
):
def __init__(
self,
ism,
dasturlash_tili
):
super().__init__(
ism
)
self.dasturlash_tili = (
dasturlash_tili
)
Foydalanish:
dasturchi = Dasturchi(
"Softromeda",
"Python"
)
print(
dasturchi.ism
)
print(
dasturchi.dasturlash_tili
)
super()¶
super() ota classdagi metodga murojaat qilish uchun ishlatiladi.
class Inson:
def __init__(
self,
ism
):
self.ism = ism
class Dasturchi(
Inson
):
def __init__(
self,
ism,
tajriba
):
super().__init__(
ism
)
self.tajriba = tajriba
Bu kod:
super().__init__(
ism
)
orqali Inson.__init__()ni chaqiradi.
Metodni qayta aniqlash¶
Bola class ota classdagi metodni o‘zgartirishi mumkin.
class Inson:
def salomlash(
self
):
print(
"Salom!"
)
class Dasturchi(
Inson
):
def salomlash(
self
):
print(
"Salom, men dasturchiman!"
)
Foydalanish:
inson = Inson()
dasturchi = Dasturchi()
inson.salomlash()
dasturchi.salomlash()
Natija:
Salom!
Salom, men dasturchiman!
Bu overriding deyiladi.
Polimorfizm¶
Polimorfizm — bir xil metod nomi turli obyektlarda turlicha ishlashi.
class Dasturchi:
def kasbni_aytish(
self
):
print(
"Men dasturchiman."
)
class Muhandis:
def kasbni_aytish(
self
):
print(
"Men muhandisman."
)
kasblar = [
Dasturchi(),
Muhandis()
]
for kasb in kasblar:
kasb.kasbni_aytish()
Natija:
Men dasturchiman.
Men muhandisman.
Bir xil metod:
kasb.kasbni_aytish()
turli obyektlarda turlicha ishladi.
Inkapsulyatsiya¶
Inkapsulyatsiya obyektning ichki ma’lumotlarini nazorat qilish va tashqi kod bilan qanday ishlashini belgilash g‘oyasidir.
Python'da nom oldiga _ qo‘yish odatda ichki foydalanish uchun ekanini bildiradi.
class Hisob:
def __init__(
self,
balans
):
self._balans = balans
def balansni_olish(
self
):
return self._balans
Foydalanish:
hisob = Hisob(
100000
)
print(
hisob.balansni_olish()
)
Ikki pastki chiziq¶
__ bilan boshlanadigan atributlar name mangling mexanizmidan foydalanadi.
class Hisob:
def __init__(
self,
balans
):
self.__balans = balans
Tashqaridan:
hisob = Hisob(
100000
)
print(
hisob.__balans
)
to‘g‘ridan-to‘g‘ri ishlamaydi.
Odatda unga metod orqali murojaat qilinadi:
class Hisob:
def __init__(
self,
balans
):
self.__balans = balans
def balansni_olish(
self
):
return self.__balans
Property¶
@property atributga metod kabi boshqariladigan kirish yaratishga imkon beradi.
class Foydalanuvchi:
def __init__(
self,
ism
):
self._ism = ism
@property
def ism(
self
):
return self._ism
Foydalanish:
foydalanuvchi = Foydalanuvchi(
"Softromeda"
)
print(
foydalanuvchi.ism
)
Bu yerda:
foydalanuvchi.ism
metod chaqirishga o‘xshab:
foydalanuvchi.ism()
yozilmaydi.
Property orqali qiymatni tekshirish¶
class Foydalanuvchi:
def __init__(
self,
yosh
):
self.yosh = yosh
@property
def yosh(
self
):
return self._yosh
@yosh.setter
def yosh(
self,
qiymat
):
if qiymat < 0:
raise ValueError(
"Yosh manfiy bo‘lishi mumkin emas."
)
self._yosh = qiymat
Endi:
foydalanuvchi = Foydalanuvchi(
25
)
print(
foydalanuvchi.yosh
)
Noto‘g‘ri qiymat:
foydalanuvchi.yosh = -5
xatolik chiqaradi.
Maxsus metodlar¶
Python'da __ bilan boshlanadigan maxsus metodlar mavjud.
Masalan:
__init__
__str__
__repr__
__len__
__eq__
Ular Python tomonidan maxsus vaziyatlarda chaqiriladi.
__str__¶
Obyektni foydalanuvchiga tushunarli ko‘rinishda chiqarish uchun __str__ ishlatiladi.
class Foydalanuvchi:
def __init__(
self,
ism,
yosh
):
self.ism = ism
self.yosh = yosh
def __str__(
self
):
return (
f"{self.ism}, "
f"{self.yosh} yosh"
)
Foydalanish:
foydalanuvchi = Foydalanuvchi(
"Softromeda",
25
)
print(
foydalanuvchi
)
Natija:
Softromeda, 25 yosh
__len__¶
Obyekt uchun len() qanday ishlashini belgilash mumkin.
class Jamoa:
def __init__(
self,
azolar
):
self.azolar = azolar
def __len__(
self
):
return len(
self.azolar
)
Foydalanish:
jamoa = Jamoa(
[
"Ali",
"Vali",
"Sami"
]
)
print(
len(jamoa)
)
Natija:
3
__eq__¶
Ikki obyektni == bilan solishtirishni belgilash mumkin.
class Foydalanuvchi:
def __init__(
self,
ism
):
self.ism = ism
def __eq__(
self,
boshqa
):
return (
self.ism
== boshqa.ism
)
Foydalanish:
birinchi_foydalanuvchi = Foydalanuvchi(
"Ali"
)
ikkinchi_foydalanuvchi = Foydalanuvchi(
"Ali"
)
print(
birinchi_foydalanuvchi
== ikkinchi_foydalanuvchi
)
Natija:
True
Kompozitsiya¶
Obyekt boshqa obyektni o‘z ichida saqlashi mumkin.
Masalan:
class Dvigatel:
def ishga_tushirish(
self
):
print(
"Dvigatel ishga tushdi."
)
class Mashina:
def __init__(
self
):
self.dvigatel = Dvigatel()
def ishga_tushirish(
self
):
self.dvigatel.ishga_tushirish()
Foydalanish:
mashina = Mashina()
mashina.ishga_tushirish()
Bu yerda Mashina ichida Dvigatel obyekti mavjud.
Bir nechta meros olish¶
Python bir nechta classdan meros olishga imkon beradi.
class Yuruvchi:
def yurish(
self
):
print(
"Yurish amalga oshirildi."
)
class Suzuvchi:
def suzish(
self
):
print(
"Suzish amalga oshirildi."
)
class Sportchi(
Yuruvchi,
Suzuvchi
):
pass
Foydalanish:
sportchi = Sportchi()
sportchi.yurish()
sportchi.suzish()
MRO¶
Bir nechta meros olishda Python metodni qaysi classdan izlash tartibini MRO orqali belgilaydi.
print(
Sportchi.mro()
)
MRO:
Method Resolution Order
ya’ni metodlarni qidirish tartibi.
Abstract class¶
Ba’zan ota class faqat umumiy interfeysni belgilashi kerak.
Buning uchun abc modulidan foydalanish mumkin.
from abc import ABC, abstractmethod
class Transport(
ABC
):
@abstractmethod
def harakatlanish(
self
):
pass
Endi bola class bu metodni amalga oshirishi kerak:
class Mashina(
Transport
):
def harakatlanish(
self
):
print(
"Mashina yo‘lda harakatlanmoqda."
)
Obyektlar bilan ishlash¶
Bir nechta foydalanuvchini listda saqlash mumkin.
class Foydalanuvchi:
def __init__(
self,
ism,
yosh
):
self.ism = ism
self.yosh = yosh
def malumot_korsatish(
self
):
print(
f"{self.ism} - "
f"{self.yosh} yosh"
)
foydalanuvchilar = [
Foydalanuvchi(
"Ali",
25
),
Foydalanuvchi(
"Vali",
30
),
Foydalanuvchi(
"Sami",
28
)
]
for foydalanuvchi in foydalanuvchilar:
foydalanuvchi.malumot_korsatish()
Obyektlardan foydalanishning foydasi¶
Oddiy dasturda ma’lumotlar:
ism = "Ali"
yosh = 25
kasb = "Dasturchi"
ko‘rinishida bo‘lishi mumkin.
Class yordamida esa:
class Foydalanuvchi:
def __init__(
self,
ism,
yosh,
kasb
):
self.ism = ism
self.yosh = yosh
self.kasb = kasb
def malumot_korsatish(
self
):
print(
f"Ism: {self.ism}"
)
print(
f"Yosh: {self.yosh}"
)
print(
f"Kasb: {self.kasb}"
)
Ma’lumot va ular bilan ishlaydigan xatti-harakatlar bir joyda jamlanadi.
Amaliy mashqlar¶
Mashq 1¶
Foydalanuvchi classini yarating.
U quyidagilarni saqlasin:
ism
yosh
email
Mashq 2¶
Foydalanuvchi classiga:
malumot_korsatish()
metodini qo‘shing.
Mashq 3¶
Hisob classini yarating.
Unda:
pul_qoshish()
pul_yechish()
balansni_korsatish()
metodlari bo‘lsin.
Mashq 4¶
Transport classidan:
Mashina
Velosiped
classlarini meros qildiring.
Mashq 5¶
Har ikkala classda:
harakatlanish()
metodini alohida amalga oshiring.
Mashq 6¶
@property yordamida yoshni tekshiring.
Mashq 7¶
__str__ metodini amalga oshiring.
Mashq 8¶
Ikki obyektni == orqali solishtirish uchun __eq__ metodini yozing.
Mini loyiha — Softromeda hisob tizimi¶
class Hisob:
def __init__(
self,
egasi
):
self.egasi = egasi
self._balans = 0
@property
def balans(
self
):
return self._balans
def pul_qoshish(
self,
miqdor
):
if miqdor <= 0:
raise ValueError(
"Qo‘shiladigan pul 0 dan katta bo‘lishi kerak."
)
self._balans += miqdor
def pul_yechish(
self,
miqdor
):
if miqdor <= 0:
raise ValueError(
"Yechiladigan pul 0 dan katta bo‘lishi kerak."
)
if miqdor > self._balans:
raise ValueError(
"Balansda yetarli mablag‘ mavjud emas."
)
self._balans -= miqdor
def malumot_korsatish(
self
):
print(
f"Hisob egasi: {self.egasi}"
)
print(
f"Balans: {self._balans}"
)
def __str__(
self
):
return (
f"{self.egasi}: "
f"{self._balans} so‘m"
)
hisob = Hisob(
"Softromeda"
)
try:
hisob.pul_qoshish(
500000
)
hisob.pul_yechish(
150000
)
hisob.malumot_korsatish()
print(
hisob
)
except ValueError as xatolik:
print(
f"Xatolik: {xatolik}"
)
Natija:
Hisob egasi: Softromeda
Balans: 350000
Softromeda: 350000 so‘m
Bob xulosasi¶
Bu bobda Python'da obyektga yo‘naltirilgan dasturlashni o‘rgandik.
Asosiy tushunchalar:
class
obyekt
atribut
metod
self
__init__
Classlar orasidagi munosabatlar:
meros olish
super()
overriding
polimorfizm
kompozitsiya
Qo‘shimcha imkoniyatlar:
classmethod
staticmethod
property
abstractmethod
Maxsus metodlar:
__init__
__str__
__repr__
__len__
__eq__
Obyektga yo‘naltirilgan dasturlash katta dasturlarni ma’lumotlar va ularning xatti-harakatlari asosida tartibli tashkil qilishga yordam beradi.
Keyingi bobda Python modullari, paketlar, import tizimi va loyihalarni bir nechta faylga ajratishni o‘rganamiz.