⬅️ Bosh sahifaga
1 / 12

📚 Python OOP - 15-dars

Property Decorator

Inkapsulatsiyani chuqurlashtirish

Assalomu alaykum, yosh dasturchilar! 😊
Bugun biz @property dekoratori va getter/setter metodlarini o'rganamiz

120 daqiqa

📋 Dars rejasi

🤔 Muammo

Avvalgi darsda biz getter va setter metodlarini ko'rdik:

class Shaxs:
    def __init__(self, ism):
        self.__ism = ism  # Private atribut

    def get_ism(self):
        return self.__ism

    def set_ism(self, yangi_ism):
        self.__ism = yangi_ism

shaxs = Shaxs("Ali")
print(shaxs.get_ism())  # Ali
shaxs.set_ism("Vali")
print(shaxs.get_ism())  # Vali

Muammo: Bu usul biroz noqulay, chunki atributga to'g'ridan-to'g'ri kirish o'rniga metod chaqirish kerak.

Yechim: @property dekoratori yordamida buni soddalashtiramiz!

🔧 @property dekoratori

@property dekoratori atributlarga kirishni boshqarish uchun ishlatiladi:

class Talaba:
    def __init__(self, ism, yosh):
        self.ism = ism
        self.__yosh = yosh  # Private atribut
    
    @property
    def yosh(self):
        """Getter metodi - @property dekoratori bilan"""
        return self.__yosh
    
    @yosh.setter
    def yosh(self, yangi_yosh):
        """Setter metodi - @yosh.setter dekoratori bilan"""
        if 0 < yangi_yosh < 100:
            self.__yosh = yangi_yosh
        else:
            raise ValueError("Yosh 0 va 100 orasida bo'lishi kerak!")
    
    def malumot(self):
        return f"Ism: {self.ism}, Yosh: {self.yosh}"

# Test qilish
talaba = Talaba("Sardor", 18)
print(talaba.yosh)        # 18 (getter chaqiriladi)
talaba.yosh = 19          # setter chaqiriladi
print(talaba.malumot())   # Ism: Sardor, Yosh: 19

🔒 Faqat getter (read-only)

Ba'zi atributlarni faqat o'qish uchun qoldirish mumkin:

class Bank_Hisob:
    def __init__(self, ism, boshlangich_summa):
        self.ism = ism
        self.__summa = boshlangich_summa
        self.__hisob_raqami = f"UZ{len(ism)}{hash(ism) % 10000}"
    
    @property
    def summa(self):
        """Faqat o'qish uchun - setter yo'q"""
        return self.__summa
    
    @property
    def hisob_raqami(self):
        """Hisob raqami o'zgartirilmaydi"""
        return self.__hisob_raqami
    
    def pul_qoshish(self, miqdor):
        if miqdor > 0:
            self.__summa += miqdor
            return f"{miqdor} so'm qo'shildi"
        else:
            return "Noto'g'ri miqdor!"

# Test qilish
hisob = Bank_Hisob("Ali", 100000)
print(f"Hisob raqami: {hisob.hisob_raqami}")  # UZ3xxxx
print(f"Summa: {hisob.summa}")                # 100000
print(hisob.pul_qoshish(50000))               # 50000 so'm qo'shildi
print(f"Yangi summa: {hisob.summa}")          # 150000

# hisob.summa = 200000  # Xatolik! setter yo'q

🏠 Murakkab misol

Uy sinfi bilan to'liq misol:

class Uy:
    def __init__(self, manzil, maydon, narx):
        self.manzil = manzil
        self.__maydon = maydon
        self.__narx = narx
    
    @property
    def maydon(self):
        return self.__maydon
    
    @maydon.setter
    def maydon(self, yangi_maydon):
        if yangi_maydon > 0:
            self.__maydon = yangi_maydon
        else:
            raise ValueError("Maydon musbat bo'lishi kerak!")
    
    @property
    def narx(self):
        return self.__narx
    
    @narx.setter
    def narx(self, yangi_narx):
        if yangi_narx > 0:
            self.__narx = yangi_narx
        else:
            raise ValueError("Narx musbat bo'lishi kerak!")
    
    @property
    def narx_per_m2(self):
        """Har kvadrat metr uchun narx"""
        return self.__narx / self.__maydon
    
    def malumot(self):
        return f"Manzil: {self.manzil}, Maydon: {self.maydon}m², Narx: {self.narx} so'm"

# Test qilish
uy = Uy("Toshkent", 100, 50000000)
print(uy.malumot())
print(f"1m² narxi: {uy.narx_per_m2} so'm")

uy.maydon = 120
uy.narx = 60000000
print(uy.malumot())
print(f"Yangi 1m² narxi: {uy.narx_per_m2} so'm")

⚖️ Qiyoslash

Eski usul (getter/setter metodlari):

class Eski_Talaba:
    def __init__(self, yosh):
        self.__yosh = yosh
    
    def get_yosh(self):
        return self.__yosh
    
    def set_yosh(self, yangi_yosh):
        self.__yosh = yangi_yosh

talaba = Eski_Talaba(18)
print(talaba.get_yosh())  # Metod chaqirish kerak
talaba.set_yosh(19)       # Metod chaqirish kerak

Yangi usul (@property):

class Yangi_Talaba:
    def __init__(self, yosh):
        self.__yosh = yosh
    
    @property
    def yosh(self):
        return self.__yosh
    
    @yosh.setter
    def yosh(self, yangi_yosh):
        self.__yosh = yangi_yosh

talaba = Yangi_Talaba(18)
print(talaba.yosh)  # Atribut kabi ishlatish
talaba.yosh = 19    # Atribut kabi o'zgartirish

💪 Amaliy mashq 1

🚗 Mashina sinfi

Vazifa: Mashina sinfini @property bilan yarating

  • model - public atribut
  • __tezlik - private atribut (0-200 km/h)
  • @property tezlik - getter
  • @tezlik.setter - setter (0-200 orasida)
  • @property tezlik_holati - tezlikka qarab holat

Vaqt: 10 daqiqa

💪 Amaliy mashq 2

📱 Telefon sinfi

Vazifa: Telefon sinfini @property bilan yarating

  • model - public atribut
  • __battery - private atribut (0-100%)
  • @property battery - getter
  • @battery.setter - setter (0-100 orasida)
  • @property battery_holati - battery ga qarab holat

Vaqt: 10 daqiqa

🏠 Uy vazifasi

👨‍🎓 Vazifa 1: Talaba sinfi
  • ism - public atribut
  • __baho - private atribut (0-100)
  • @property baho - getter
  • @baho.setter - setter (0-100 orasida)
  • @property baho_holati - bahoga qarab holat
🏦 Vazifa 2: Bank hisobi
  • ism - public atribut
  • __summa - private atribut
  • @property summa - faqat getter
  • @property hisob_raqami - faqat getter
  • Pul qo'shish va olish metodlari
🏠 Vazifa 3: Uy sinfi
  • manzil - public atribut
  • __maydon - private atribut
  • __narx - private atribut
  • @property bilan barcha atributlar
  • @property narx_per_m2 - hisoblangan property

🎉 Xulosa

Bugun nimalarni o'rgandik?

🔧 @property dekoratori

Getter metodini atribut kabi ishlatish

🔧 @setter dekoratori

Setter metodini atribut kabi ishlatish

🔒 Read-only property

Faqat o'qish uchun property

🧮 Computed property

Hisoblangan property

Keyingi dars: Abstract Classes mavzusini o'rganamiz

Savollaringiz bo'lsa, yozib qoldiring! 😊

🔄 Qayta ko'rib chiqish

Savollar:

  • @property dekoratori nima uchun kerak?
  • Getter va setter o'rtasidagi farq nima?
  • Read-only property qanday yaratiladi?
  • Computed property nima?

💡 Muhim eslatma:

@property dekoratori yordamida inkapsulatsiyani saqlab, kodni yanada qulay va o'qish uchun oson qilish mumkin!