Python logo

Python dasturlash tili: 9.2-dars

9.2 Klass va ob’yekt o’zgaruvchilari

Klass va ob’ektlarning fuksional qismi, ya’ni metodlarni avvalgi darsda ko’rib o’tdik. Bu darsda klass maydonlari haqida so’z yuritamiz. Klass yoki ob’ekt maydonlarining oddiy o’zgaruvchilardan farqi ular shu klass yoki ob’ekt sohasiga tegishli bo’ladi. Ya’ni maydon nomlari shu klass yoki ob’ekt ichida mavjud bo’ladi. Moydon – o’zgaruvchilarning ikki turi mavjud: Klass o’zgaruvchlari va ob’yekt o’zgaruvchilari.

Ularning asosiy farqlari quyidagicha:

Klass o’zgaruvchilariga shu klassning barcha ob’yektlari tomonidan murojaat qilish imkoniyati mavjud. Klass o’zgaruvchisi hamma ob’yektlar uchun bitta bo’ladi. Shuning uchun biror ob’yekt klass o’zgaruvchisini o’zgartirsa bu o’zgarish shu klassning qolgan ob’yektlarida ham ko’rinadi.

Ob’yekt o’zgaruvchilari esa, klassning har bir ob’yektining o’zigagina tegishli bo’ladi.

Bir ob’yekt o’zgaruvchisining o’zgartirilishi boshqa ob’yektlarga ta’sirqilmaydi.

Misol: (objvar.py nomi bilan saqlang)

  1. class Robot:
  2.  
  3. '''Nomlangan robotlarni ifoda etadi'''
  4.  
  5. # Klass o'zgaruvchisi robotlar sonini ifoda etadi
  6. population = 0
  7.  
  8. def __init__(self, name):
  9. '''Ma'lumotlar inisializatsiyasi.'''
  10. self.name = name
  11.  
  12. print('(Inisializatsiya {0})'.format(self.name))
  13.  
  14. # Yangi robot xosil qilinayotganda 'population' o'zgaruvchisiga qo'shiladi
  15. Robot.population += 1
  16.  
  17.  
  18. def __del__(self):
  19. '''Robot yo'q qilinyapti.'''
  20. print("{0} yo'q qilinyapti!".format(self.name))
  21.  
  22. Robot.population -= 1
  23.  
  24. if Robot.population == 0:
  25. print('{0} oxirgisi edi.'.format(self.name))
  26. else:
  27. print('{0:d} ta ishchi robotlar qoldi.'.format(Robot.population))
  28.  
  29.  
  30. def sayHi(self):
  31. '''Robotlar salomlasha olishadi'''
  32. print('Salom! Mening nomim {0}.'.format(self.name))
  33.  
  34.  
  35. def howMany():
  36. '''Robotlar sonini chop qiladi.'''
  37. print('Bizda {0:d} ta robot bor.'.format(Robot.population))
  38.  
  39.  
  40. howMany = staticmethod(howMany)
  41.  
  42.  
  43. droid1 = Robot('R2-D2')
  44. droid1.sayHi()
  45.  
  46. Robot.howMany()
  47.  
  48. droid2 = Robot('C-3PO')
  49. droid2.sayHi()
  50.  
  51. Robot.howMany()
  52.  
  53. print("\nBu yerda robotlar qandaydir ishlarni qilishlari mumkin.\n")
  54.  
  55. print("Robotlar ishlarini qilib bo'ldi. Keling, ularni yo'q qilamiz.\n")
  56.  
  57. del droid1
  58. del droid2
  59.  
  60. Robot.howMany()

 

Natija:

python objvar.py

(Inisializatsiya R2-D2)

Salom! Mening nomim R2-D2.

Bizda 1 ta robot bor.

(Inisializatsiya C-3PO)

Salom! Mening nomim C-3PO.

Bizda 2 ta robot bor.

 

Bu yerda robotlar qandaydir ishlarni qilishlari mumkin.

Robotlar ishlarini qilib bo’ldi. Keling, ularni yo’q qilamiz.

 

R2-D2 yo’q qilinyapti!

1 ta ishchi robotlar qoldi.

C-3PO yo’q qilinyapti!

C-3PO oxirgisi edi.

Bizda 0 ta robot bor.

 

Bu qanday ishlaydi:

Bu yerda population klass o’zgaruvchisi hisoblanadi. name ob’yekt o’zgaruvchisi hisoblanadi.

Klass o’zgaruvchisiga self.population tarzida emas, Robot.population tarzida murojaat qilamiz. name ob’yekt o’zgaruvchisiga esa, self.name tarzida, barcha ob’yektlar ichida murojaat qilishimiz mumkin.

howMany metodi klassga tegishli, klass ob’yektiga emas. Bu shuni anglatadiki, biz uni classmethod yoki staticmethod ko’rinishida aniqlashimiz mumkin.

Bunga dekoratorlardan foydalanib xam erishish mumkin:

  1. @staticmethod
  2. def howMany():
  3. '''Robotlar sonini chop qiladi.'''
  4. print('Bizda {0:d} ta robot bor.'.format(Robot.population))

__init__ metodida har bir xosil qilingan robot uchun population klass o’zgaruvchisini birga oshiryapmiz. self.name esa har bir ob’yektning o’zigagina tegishlik.

__init__ metodi bilan bir qatorda __del__ metodi ham mavjud bo’lib, bu metod qachonki ob’yekt o’chirilayotganda chaqiriladi va uning xotirada egallagan joyi operasion tizimiga keyingi ishlatishlar uchun qaytariladi. Bu metodda biz Robot.population klass o’zgaruvchisini birga kamaytiramiz.

 

Meros olish

Ob’yektga yo’naltirilgan dasturlashning ya’na bir katta afzalligi biror kod bo’lagini bir necha marta qayta ishlatish imkoniyatidir. Bu imkoniyatga meros olish mexanizmi bilan erishish mumkin.

Aytaylik, biz kollejdagi o’qituvchilar va talabalar haqidagi ma’lumotlarni o’zida jamlovchi dastur tuzmoqchimiz. Ularning bir nechta umumiy xususiyatlari bor: ismi, yoshi va manzili. Va ya’na aloxida xususiyatlari ham mavjud: o’qituvchilar uchun maosh, dars kurslari, ta’til, talabalar uchun baxo va o’qish uchun to’lov.

O’qituvchilar va talabalar uchun alohida-alohida klass tuzish mumkin, lekin ular uchun umumiy bo’lgan biror xusisiyat qo’shishga to’g’ri keladigan bo’lsa, u holda har bir klass uchun bu xususiyatni qo’shib chiqish kerak bo’ladi.

Eng yaxshisi SchoolMember degan umumiy klass qilish kerakda va shu klassdan o’qituvchilar va talabal klasslari meros olsin. Shunda o’qituvchi va talabalar uchun umumiy bo’lgan xususiyatlarni SchoolMember asos klassga qo’shish mumkin bo’ladi.

Bu usulning bir nechta afzalliklari bor. Agar biz SchoolMember klassida biror metodni yoki xususiyatni o’zgartirsak yoki qo’shsak bu o’zgarishlar avtomatik o’qituvchilar va talabalar klasslarida (SchoolMember ning bola klasslarida) o’z aksini topadi. Misol uchun, biz o’qituvchilar va talabalar hujjatlari uchun yangi xususiyatni SchoolMember asos klassga qo’shishimiz mumkin.

Misol: (inherit.py nomi bilan saqlang)

  1. class SchoolMember:
  2. '''Maktabdagi ixtiyoriy shaxsni ifoda etadi.'''
  3.  
  4. def __init__(self, name, age):
  5. self.name = name
  6. self.age = age
  7.  
  8. print('(SchoolMember hosil qilindi: {0})'.format(self.name))
  9.  
  10.  
  11. def tell(self):
  12. '''Ma'lumotni chop qilish.'''
  13. print('Ismi:"{0}" Yoshi:"{1}"'.format(self.name, self.age), end=" ")
  14.  
  15.  
  16. class Teacher(SchoolMember):
  17. '''O'qituvchilarni ifoda etadi.'''
  18.  
  19. def __init__(self, name, age, salary):
  20. SchoolMember.__init__(self, name, age)
  21. self.salary = salary
  22.  
  23. print('(Teacher hosil qilindi: {0})'.format(self.name))
  24.  
  25.  
  26. def tell(self):
  27. SchoolMember.tell(self)
  28. print('Maoshi: "{0:d}"'.format(self.salary))
  29.  
  30.  
  31. class Student(SchoolMember):
  32. '''Talabalarni ifoda etadi.'''
  33.  
  34. def __init__(self, name, age, marks):
  35. SchoolMember.__init__(self, name, age)
  36. self.marks = marks
  37.  
  38. print('(Student hosil qilindi: {0})'.format(self.name))
  39.  
  40.  
  41. def tell(self):
  42. SchoolMember.tell(self)
  43. print('Bahosi: "{0:d}"'.format(self.marks))
  44.  
  45.  
  46. t = Teacher('Mrs. Shrividya', 40, 30000)
  47. s = Student('Swaroop', 25, 75)
  48.  
  49. print() # Bo'sh qator chop qiladi
  50.  
  51. members = [t, s]
  52.  
  53. for member in members:
  54. member.tell() # O'qituvchi uchun ham talaba uchun ham ishlaydi

Natija:

$ python3 inherit.py

(SchoolMember hosil qilindi: Mrs. Shrividya)

(Teacher hosil qilindi: Mrs. Shrividya)

(SchoolMember hosil qilindi: Swaroop)

(Student hosil qilindi: Swaroop)

 

Ismi:”Mrs. Shrividya” Yoshi:”40″ Maoshi: “30000”

Ismi:”Swaroop” Yoshi:”25″ Baxosi: “75”

Bu qanday ishlaydi:

Meros olish imkoniyatidan foydalanish uchun klassni e’lon qilish joyida shu klass nomidan keyinoq kortejda asos klass nomini ko’rsatamiz. Asos klassning __init__ metodida ob’yekt qismining asos klassga tegishli bo’lgan xusisiyatlarni inisializatsiya qilamiz. Buni eslab qolish juda muhim: Python asos klassning __init__ metodini avtomat tarzda chaqirmaydi, uni ochiq oydin qilib chaqirish kerak bo’ladi.

(119 marta o'qilgan, bugun 1 marta o'qildi)

O'xshash maqolalar: