Assalomu alaykum, yosh dasturchilar! ๐
Bugun biz Python'ning juda qiziqarli va kuchli xususiyati - Decorators'ni o'rganamiz
Decorator - bu funksiya yoki class'ni boshqa funksiya yoki class bilan "o'rab" olish va uning xatti-harakatini o'zgartirish.
๐ก Real hayotdan misol:
Agar sizda uyingiz bo'lsa, siz uni bezash uchun gul, rasmlar, mebellar qo'shasiz. Bu narsalar uyingizning asosiy funksiyasini o'zgartirmaydi, lekin uni chiroyliroq qiladi. Decorators ham xuddi shunday - ular funksiyalar yoki class'larni "bezaydi" va ularning funksiyasini kengaytiradi.
def bezash_decorator(func):
def ichki_funksiya():
print("=== Funksiya boshlanmoqda ===")
func()
print("=== Funksiya tugadi ===")
return ichki_funksiya
@bezash_decorator
def salom_aytish():
print("Salom, dunyo!")
# Test qilish
salom_aytish()
Takroriy kodlarni kamaytirish
Mavjud kodni o'zgartirmasdan yangi xususiyatlar qo'shish
Mantiqiy tuzilish
Bir decorator'ni ko'p joyda ishlatish
@property decorator - getter va setter'ni oddiy attribute kabi ishlatish imkonini beradi.
class Talaba:
def __init__(self, ism, yosh):
self.ism = ism
self._yosh = yosh # Protected attribute
self.__ball = 0 # Private attribute
@property
def yosh(self):
return self._yosh
@yosh.setter
def yosh(self, yangi_yosh):
if 16 <= yangi_yosh <= 25:
self._yosh = yangi_yosh
print(f"Yosh {yangi_yosh} ga o'zgartirildi")
else:
print("Yosh 16-25 orasida bo'lishi kerak!")
@property
def ball(self):
return self.__ball
@ball.setter
def ball(self, yangi_ball):
if 0 <= yangi_ball <= 100:
self.__ball = yangi_ball
print(f"Ball {yangi_ball} ga o'zgartirildi")
else:
print("Ball 0-100 orasida bo'lishi kerak!")
@property
def baho(self):
if self.__ball >= 90:
return "A'lo"
elif self.__ball >= 80:
return "Yaxshi"
elif self.__ball >= 70:
return "Qoniqarli"
else:
return "Qoniqarsiz"
def ma_lumot_ko_rsatish(self):
print(f"=== {self.ism} ma'lumotlari ===")
print(f"Yosh: {self.yosh}")
print(f"Ball: {self.ball}")
print(f"Baho: {self.baho}")
# Test qilish
talaba = Talaba("Ali", 18)
talaba.ma_lumot_ko_rsatish()
# Property'lar oddiy attribute kabi ishlatiladi
talaba.yosh = 19 # Setter ishlaydi
talaba.ball = 85 # Setter ishlaydi
print(f"Yosh: {talaba.yosh}") # Getter ishlaydi
print(f"Ball: {talaba.ball}") # Getter ishlaydi
print(f"Baho: {talaba.baho}") # Getter ishlaydi
@classmethod
def universitet_haqida(cls):
print(f"Bu {cls.universitet} universiteti!")
print(f"Jami talabalar soni: {cls.talabalar_soni}")
@classmethod
def yangi_talaba(cls, ism, yosh, kurs):
print(f"Yangi talaba qabul qilindi: {ism}")
return cls(ism, yosh, kurs)
@staticmethod
def yosh_tekshirish(yosh):
if yosh >= 16:
return "Talaba bo'lish mumkin"
else:
return "Yosh yetarli emas"
@staticmethod
def ball_hisoblash(imtihon_balli, maksimal_ball):
foiz = (imtihon_balli / maksimal_ball) * 100
if foiz >= 90:
return "A'lo"
elif foiz >= 80:
return "Yaxshi"
elif foiz >= 70:
return "Qoniqarli"
else:
return "Qoniqarsiz"
# Test qilish
print("=== Class Method test ===")
Talaba.universitet_haqida()
print("\n=== Static Method test ===")
print(Talaba.yosh_tekshirish(18)) # Class orqali
print(Talaba.ball_hisoblash(85, 100)) # Class orqali
print("\n=== Object yaratish ===")
talaba1 = Talaba("Ali", 18, 1)
talaba2 = Talaba("Zilola", 19, 2)
print("\n=== Class Method object orqali ===")
talaba1.universitet_haqida() # Object orqali ham ishlaydi
print("\n=== Static Method object orqali ===")
print(talaba1.yosh_tekshirish(17)) # Object orqali ham ishlaydi
print("\n=== Yangi talaba yaratish ===")
talaba3 = Talaba.yangi_talaba("Sardor", 20, 3)
Custom decorators - o'zingizning decorator'lar yaratish.
def vaqt_olchash(func):
import time
def ichki_funksiya(*args, **kwargs):
boshlanish = time.time()
natija = func(*args, **kwargs)
tugash = time.time()
print(f"{func.__name__} funksiyasi {tugash - boshlanish:.4f} soniya davom etdi")
return natija
return ichki_funksiya
def parol_tekshirish(func):
def ichki_funksiya(*args, **kwargs):
parol = input("Parolni kiriting: ")
if parol == "1234":
return func(*args, **kwargs)
else:
print("Noto'g'ri parol!")
return None
return ichki_funksiya
def ma_lumot_tekshirish(func):
def ichki_funksiya(*args, **kwargs):
print(f"=== {func.__name__} funksiyasi chaqirildi ===")
print(f"Argumentlar: {args}")
print(f"Kalit so'zlar: {kwargs}")
natija = func(*args, **kwargs)
print(f"Natija: {natija}")
print("=== Funksiya tugadi ===")
return natija
return ichki_funksiya
# Decorators ishlatish
@vaqt_olchash
@ma_lumot_tekshirish
def hisoblash(a, b):
return a + b
@parol_tekshirish
def maxfiy_ma_lumot():
return "Bu maxfiy ma'lumot!"
# Test qilish
print("=== Hisoblash funksiyasi ===")
natija = hisoblash(5, 3)
print(f"Natija: {natija}")
print("\n=== Maxfiy ma'lumot ===")
maxfiy = maxfiy_ma_lumot()
if maxfiy:
print(maxfiy)
def parol_tekshirish(func):
def ichki_funksiya(self, *args, **kwargs):
parol = input("Parolni kiriting: ")
if parol == self._parol:
return func(self, *args, **kwargs)
else:
print("Noto'g'ri parol!")
return None
return ichki_funksiya
def ma_lumot_tekshirish(func):
def ichki_funksiya(self, *args, **kwargs):
print(f"=== {func.__name__} funksiyasi chaqirildi ===")
natija = func(self, *args, **kwargs)
print("=== Funksiya tugadi ===")
return natija
return ichki_funksiya
class BankHisob:
def __init__(self, ism, dastlabki_summa=0):
self.ism = ism
self._balans = dastlabki_summa
self._parol = "1234"
self._max_kunlik_chiqim = 1000000
self._kunlik_chiqim = 0
self._harakatlar = []
@property
def balans(self):
return self._balans
@balans.setter
def balans(self, yangi_balans):
if yangi_balans >= 0:
self._balans = yangi_balans
else:
print("Balans manfiy bo'lishi mumkin emas!")
@property
def kunlik_chiqim(self):
return self._kunlik_chiqim
@classmethod
def bank_ma_lumotlari(cls):
print("=== Bank ma'lumotlari ===")
print("Bank nomi: Toshkent Bank")
print("Bosh ofis: Toshkent shahar")
print("Telefon: +998 71 123 45 67")
@staticmethod
def foiz_hisoblash(summa, foiz, yil):
return summa * (1 + foiz/100) ** yil
@staticmethod
def parol_tekshirish(parol):
if len(parol) >= 4 and parol.isdigit():
return True
else:
return False
@parol_tekshirish
@ma_lumot_tekshirish
def pul_qo_shish(self, miqdor):
if miqdor > 0:
self._balans += miqdor
self._harakatlar.append(f"+{miqdor} so'm")
print(f"{miqdor} so'm qo'shildi. Yangi balans: {self._balans}")
else:
print("Miqdor musbat bo'lishi kerak!")
@parol_tekshirish
@ma_lumot_tekshirish
def pul_olish(self, miqdor):
if miqdor > 0:
if self._balans >= miqdor:
if self._kunlik_chiqim + miqdor <= self._max_kunlik_chiqim:
self._balans -= miqdor
self._kunlik_chiqim += miqdor
self._harakatlar.append(f"-{miqdor} so'm")
print(f"{miqdor} so'm olindi. Yangi balans: {self._balans}")
else:
print("Kunlik chiqim limiti oshib ketdi!")
else:
print("Yetarli mablag' yo'q!")
else:
print("Miqdor musbat bo'lishi kerak!")
Funksiyalar yoki class'larni "o'rab" olish
Getter/setter'ni oddiy attribute kabi ishlatish
Class bilan ishlaydi, cls parametrini oladi
Mustaqil ishlaydi, parametr olmaydi
O'zingizning decorator'lar yaratish
Keyingi dars: Abstract Classes mavzusini o'rganamiz
Savollaringiz bo'lsa, yozib qoldiring! ๐