Paikalliset ja globaalit muuttujat
Muuttujan näkyvyysalue (scope) tarkoittaa, missä ohjelman osissa muuttujaa voi käyttää. Paikallinen muuttuja on muuttuja, joka on näkyvissä vain tietyn rajatun alueen sisällä ohjelmassa. Globaali muuttuja on puolestaan käytettävissä missä tahansa ohjelman osassa.
Paikalliset muuttujat
Pythonissa funktion sisällä määritellyt muuttujat ovat funktion paikallisia muuttujia. Tämä koskee sekä parametreja että funktion lohkon sisällä esiteltyjä muuttujia. Paikallisuus tarkoittaa, että muuttuja ei ole olemassa funktion ulkopuolella.
Esimerkiksi seuraavassa ohjelmassa yritys viitata muuttujaan x
pääohjelmassa antaa virheen:
def testi():
x = 5
print(x)
testi()
print(x)
5 NameError: name 'x' is not defined
Ohjelmassa muuttuja x
on siis olemassa vain funktion testi
suorituksen ajan eikä siihen pääse käsiksi muista funktioista tai pääohjelmasta.
Globaalit muuttujat
Pääohjelmassa eli kaikkien funktioiden ulkopuolella määritellyt muuttujat ovat globaaleja muuttujia. Globaalin muuttujan arvo voidaan lukea funktiossa. Esimerkiksi seuraava toimii:
def testi():
print(x)
x = 3
testi()
3
Kuitenkaan globaalia muuttujaa ei voi muuttaa suoraan. Esimerkiksi seuraava funktio ei vaikuta globaaliin muuttujaan:
def testi():
x = 5
print(x)
x = 3
testi()
print(x)
5 3
Tässä tapauksessa funktio testi
luo paikallisen muuttujan x
, joka saa arvon 5. Tämä on kuitenkin eri muuttuja kuin pääohjelmassa oleva muuttuja x
.
Entä miten toimii seuraava koodi?
def testi():
print(x)
x = 5
x = 3
testi()
print(x)
UnboundLocalError: local variable 'x' referenced before assignment
Funktiossa testi
annetaan arvo muuttujalle x
, jolloin Python päättelee, että x
on funktion paikallinen muuttuja (eikä globaali muuttuja). Koska muuttujaan yritetään viitata ennen arvon asettamista, tapahtuu virhe.
Jos kuitenkin haluamme muuttaa funktiossa globaalia muuttujaa, tämä onnistuu avainsanan global
avulla:
def testi():
global x
x = 3
print(x)
x = 5
testi()
print(x)
3 3
Nyt funktiossa tehty muutos x = 3
vaikuttaa myös pääohjelmaan, eli kaikissa ohjelman kohdissa x
viittaa samaan muuttujaan.
Milloin käyttää globaalia muuttujaa?
Globaalien muuttujien tarkoituksena ei ole korvata funktion parametreja tai paluuarvoa. Esimerkiksi on sinänsä mahdollista tehdä seuraava funktio, joka tallentaa laskun tuloksen globaaliin muuttujaan:
def laske_summa(a, b):
global tulos
tulos = a + b
laske_summa(2, 3)
print(tulos)
Parempi tapa on kuitenkin toteuttaa funktio kuten ennenkin:
def laske_summa(a, b):
return a + b
tulos = laske_summa(2, 3)
print(tulos)
Jälkimmäisen tavan etuna on, että funktio on itsenäinen kokonaisuus, jolle annetaan tietyt parametrit ja joka palauttaa tietyn tuloksen. Funktiolla ei ole sivuvaikutuksia, minkä ansiosta sitä voi testata muusta koodista riippumattomasti.
Kuitenkin globaali muuttuja voi olla hyödyllinen, jos halutaan pitää yllä jotain funktioille yhteistä "ylemmän tason" tietoa. Tässä on yksi esimerkki asiasta:
def laske_summa(a, b):
global laskuri
laskuri += 1
return a + b
def laske_erotus(a, b):
global laskuri
laskuri += 1
return a - b
laskuri = 0
print(laske_summa(2, 3))
print(laske_summa(5, 5))
print(laske_erotus(5, 2))
print(laske_summa(1, 0))
print("Funktioita kutsuttiin", laskuri, "kertaa")
Tässä haluamme pitää ohjelman suorituksen aikana kirjaa siitä, montako kertaa funktioita on kutsuttu ohjelman eri kohdista. Nyt globaali muuttuja laskuri
on kätevä, koska voimme kasvattaa sen arvoa jokaisella funktion kutsukerralla ja katsoa globaalista muuttujasta, montako kertaa funktiota on kutsuttu.
Vastaa lopuksi osion loppukyselyyn: