Muutuja Pythonis

Pythonis kasutatakse muutuja funktsiooni andmisel omistamise reegleid (pass by assignment). Funktsiooni parameeter on muutuja, kuhu omistatakse kaasa pandud väärtus. Selleks, et teada, kuidas see täpsemalt toimib, peame vaatama üldiseid muutujale väärtuse omistamise reegleid.

Muutuja väärtustamise puhul võrdusmärgi vasakpoolne sihtmärk on nimetus ja parempoolne väärtus on objekt. Ehk x = 2 korral x on nimi ja 2 on objekt. Kui nimi on juba seotud mõne objektiga (eelnevalt on x muutujasse omistatud näiteks 1), siis x seotakse nüüd uue väärtusega (vana seos kaob ära).

Pythonis hoitakse lihtsamaid (muutumatud, immutable) objekte mälus vaid ühekordselt. Kui näiteks nii x kui y muutujatesse määratakse väärtus 2, siis tegelikult on mälus üks objekt 2 ja mõlemad (nii x kui y) viitavad sellele objektile. Kui sellist objekti 2 pole, siis see luuakse. Sisemiselt hoitakse sõnastikku selleks, et nimi ja objekt vastavusse viia.

Muutumatu objekt, nagu ka nimi ütleb, ei saa muutuda. Kui mälus on 2, siis see ei saa kuidagi muutuda 3-ks. Avaldis x + 1 võtab x praeguse väärtuse, liidab sellele 1 juurde ning saadakse tulemus (objekt 3). Kui toimub omistamine x = x + 1, siis arvutatakse välja parem pool (saadakse objekt 3) ja nüüd kirjutatakse x nime taga olev viide ümber nii, et ta viitab 3 peale.

Vaatame koodinäidet. Pythonis saab kasutada funktsioon id(), mis tagastab mäluaadressi (sõltuvalt Pythoni implementatsioonist ei pruugi see tingimata mäluaadress olla, aga garanteeritud on see, et sama objekt mälus tagastab sama tulemuse). Sellega on võimalik jälgida, mis toimub näiteks muutujale väärtuse liitimisel:

x = 2
print(id(x))  # 9789024
x = x + 1
print(id(x))  # 9789056
print(id(3))  # 9789056

Algselt oli muutujal x üks mäluaadress, pärast liitmist viitab muutuja väärtusele 3 ja see paikneb mälus teises kohas (id() tagastab teise tulemuse). Võrdleme seda lõpus väärtusega, mis saame otse objekti 3 pärides.

Muutuvad (täpsemalt muudetavad ehk mutable) objektid on need, mille puhul on võimalik nende sisu mälus muuta. Näiteks on järjend (list) selline andmetüüp:

names = ["jack", "mary"]
print(id(names))  # 140578104131264
names.append("robb")
print(id(names))  # 140578104131264
print(names)  # ['jack', 'mary', 'robb']

Eelmise näite korral luuakse muutuja names, mis hakkab viitama mälus loodud järjendile, kus on kaks elementi sees. Kui vaatame id() funktsiooniga selle names muutuja asukohta, siis näeme, et see ei muutu ka peale elemendi lisamist. Ehk siis järjend on muudetav andmetüüp mis tähendab, et olemasolevaid andmeid mälus saab muuta.