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

Search for a command to run...

No comments yet. Be the first to comment.
Fetch is promise-based, so we should wait for the output // using .then method or await keyword. fetch("https://reqres.in/api/users") .then( response => { response.json().then( data => { con...
I started to build an API using Django and I will be documenting all the processes that I go through for myself and maybe others who are interested. In every new article, we'll go through what I have changed in the new release and explain them as we ...

I started to build an API using Django and I will be documenting all the processes that I go through for myself and maybe others who are interested. In this article, we'll go through what I have done so far and explain them as we go. Before that let ...

Bir neçə hissədən ibarət olacaq bu məqalələrdə Python-da olan classlar ilə tanış olacağıq. Xoş mütaliələr.

Ə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:
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 # <--|
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.
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.
İ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_2dəyişəninin milliyətininTurkisholması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.
Beləliklə bu məqalənin sonuna çatdıq. Bu məqalədə aşağıdakıları öyrəndik: