Python-da classlar (Hissə 2): Dəyişənlər

Python-da classlar (Hissə 2): Dəyişənlər

Giriş

Əvvəlki məqalədə class və obyektlərin yaradılması haqqında bəhs etmişdim. İndi isə classda dəyişənlər haqqında danışmaq lazımdır. Dəyişənlər (ingcə. variables) obyekt daxilində məlumatları yadda saxlamaq üçün istifadə olunur. Classda iki növ dəyişən tipi mövcuddur:

  1. İnstansiya dəyişənləri (ingcə. instance variables)
  2. Class dəyişənləri (ingcə. class variables)
class Person:
    nationality = "Azerbaijani"        # <- class variable

    def __init__(self, f_name, l_name, age):
        self.f_name = f_name        # <--| 
        self.l_name = l_name        # <--| instance variables
        self.age = age                # <--|

İnstansiya dəyişənləri

Yuxarıdakı kod parçası sənə əvvəlki məqalədən tanış gələ bilər. İnstansiya dəyişənlərinin ən məşhur əlavə edilmə yeri elə məhz __init__ metodudur və təkcə bu metodla limitlənmir. İstənilən metodda self-dən istifadə edilərək yaradılan dəyişənlər instansiya dəyişənləri sayılır.

person_1 = Person("Javid", "Khasizada", 21)
person_2 = Person("Tarigulu", "Khasizada", 26)

print(person_1.f_name, person_2.l_name)    # output: Javid, Tarigulu

name obyekt dəyişəni olduğuna görə yaratdığımız hər iki obyekt üçün müxtəlif nəticə verir. İnstansiya dəyişənlərini istifadə edə bilmək üçün object.name_of_variable şəklində yazmaq lazımdır.

Class dəyişənləri

Person classında gördüyümüz nationality dəyişəni bir class dəyişənidir. Bu tip dəyişənlər əsasən daha ümumi və ya hamı üçün eyni olan məlumatları yadda saxlamaq üçün istifadə edilir. Class dəyişənlərini istifadə edə bilmək üçün Class.name_of_variable şəklində yazmaq lazımdır.

print(Person.nationality)            # output: Azerbaijani

Məsələn, bu nümunədə fərz edirik ki, bütün yaradılacaq insan obyektləri Azərbaycan vətəndaşıdır.

Əlavə olaraq bu dəyişənlərdən həmin classa aid olan bütün obyektlər istifadə edə bilir və işlədilmə şəkli eyni instansiya dəyişənlərində olduğu kimidir.

print(person_1.nationality)            # output: Azerbaijani

Metodlar daxilində class dəyişənlərinin istifadəsi self-dən yararlanmaqla mümkündür. Bunu aşağıdakı koddan görə bilərik.

class Person:
    nationality = "Azerbaijani"        

    # some code

    def tell_nationality(self):
        return f'{self.f_name} is {self.nationality}.'

print(person_1.tell_nationality)    # Javid is Azerbaijani.

Dəyişənlər necə dəyişir?

İnstansiya dəyişənlərinin dəyərlərini dəyişmək sadəcə onlara yeni dəyərlər verməkdən ibarətdir. Bunu kodun 3-cü sətirindən də görmək olar.

person_1 = Person("Javid", "Khasizada", 21)

person_1.f_name = "JAXA"

Lakin class dəyişənlərində məsələ nisbətən fərqlidir. Gəlin aşağıdakı koda nəzər salaq.

Person.nationality = "Turkish"
print(person_1.nationality)     # output: ???
print(person_2.nationality)     # output: ???

person_1.nationality = "Hungarian"
print(person_1.nationality)     # output: ???    
print(person_2.nationality)     # output: ???

Kodda biz birinci classın özündən istifadə edərək class dəyişənini yeniləyirik, ikinci olaraq isə yaratdığımız obyekt ilə class dəyişəninə yeni dəyər veririk. Səncə ekrana hansı dəyərlər çap ediləcək?

Person.nationality = "Turkish"
print(person_1.nationality)     # output: Turkish
print(person_2.nationality)     # output: Turkish

person_1.nationality = "Hungarian"
print(person_1.nationality)     # output: Hungarian    
print(person_2.nationality)     # output: Turkish

Ümid edirəm düz tapa bildin. İndi isə gəl cavaba baxaq. Class səviyyəsində dəyişiklik edilən zaman bu bütün obyektlərdə həmin dəyərin yenilənməsi ilə nəticələnir.

Amma class dəyişənlərini obyekt səviyyəsində dəyişəndə o yalnız həmin obyektə dəyişmiş olur və qalan obyektlərə təsirsiz qalır. Bu səbəbdən də person_2 obyektinin milliyəti hələ də eynidir (sətir 7).

person_2 dəyişəninin milliyətinin Turkish olmasının səbəbi 1-ci sətirdə etdiyimiz dəyişiklikdir.

Bunun səbəbi dəyişənləri qaytararkən Pythonun Method Resolution Order (MRO) prinsipindən istifadə etməsidir. Bu mövzuya bir daha geri dönəcək olduğuma görə burda qısaca izah edəcəm. MRO Pythonun dəyişən və ya metodların dəyərlərinin nə olduğunu təyin etməyə kömək edir və kiçikdən böyüyə (obyektdən class-a doğru) doğru dəyəri axtarır. İlk tapdığı dəyəri isə geri qaytarır. Biz person_1 obyektində nationality dəyişənini obyekt səviyyəsində yenidən təyin edildiyinə (sətir 5) görə artıq Python class səviyyəsində bu dəyərin nə olduğuna baxmır və Hungarian dəyərini çap edir.

Bu mövzunu bir daha növbəti məqalələrdə ətraflı şəkildə izah etməyə çalışacam.

Biz bu nümunədən onu öyrənə bilərik ki, əgər bütün obyektlərin dəyərini dəyişmək istəyiriksə, class səviyyəsində, yalnız bir obyektə təsir etmək istəyiriksə, obyekt səviyyəsində class dəyişəninə yeni dəyər verməliyik.

Sual: Bəs birinci obyektdə dəyişiklik edib sonra class səviyyəsində dəyişiklik etsək nə baş verər?

person_1.nationality = "Hungarian"
print(person_1.nationality)     # output: Hungarian    

Person.nationality = "Turkish"
print(person_1.nationality)     # output: ???

Nə düşünürsən, Hungarian yoxsa Turkish? Məhz MRO prinsipinə görə cavab Hungarian olacaq.

Məzmun

Beləliklə bu məqalənin sonuna çatdıq. Bu məqalədə aşağıdakıları öyrəndik:

  1. İnstansiya dəyişənləri
  2. Class dəyişənləri
  3. Dəyişənlərin yenidən təyin edilməsi
  4. MRO prinsipinin səthi izahı

İstinad mənbələri

Did you find this article valuable?

Support Javid Khasizada by becoming a sponsor. Any amount is appreciated!