Programos yra skaidomos į dalis, kad būtų lengviau tvarkomos, pvz, į keils failus, arba faile kodas būna suskaidytas į funkcijas. Skirtingose programos dalyse gali pasitaikyti vienodai pavadintų kintamųjų (kaip kad skirtingose šeimose būna vaikų tais pačiais vardais) - jie tarpusavy nesimaišo, nes naudojami tik tos dalies viduje - lokaliai. O kai kurie kintamieji gali būti žinomi visoje programoje - globaliai (kaip kokie visuomenės veikėjai ar pop. žvaigždės).
Kintamųjų galiojimo sritis
def square(x): value = x * x return valueŠi funkcija skaičiuoja skaičiaus
x kvadratą. Tarkime, kad funkciją square iškviesime iš programos, kurioje taip pat yra value kintamasis, tačiau naudojamas kitais tikslais.
# pagrindinė programa value = 17 penki_kvadratu = square(5) print(penki_kvadratu, value)Kaip manote, kas bus atspausdinta? Nežinodami kaip Pitonas elgsis, galime svarstyti dvi galimybes:
- Arba Pitone yra du atskiri
valuekintamieji (vienas funkcijoje "square", kitas - už jos ribų ). Taigi,squaregrąžins 25, betvaluereikšmė pagrindinėje programoje išliks 17. Bus atspausdinama:2517. - Arba visur yra tas pats kintamasis
value. Funkcijasquarepakeičiavaluereikšmę, taigi programa atspausdins:2525.
O kaip yra iš tikro?
Matome, jog Pitonas veikia pagal pirmąjį variantą. Vykdant funkciją, Pitonas nepakeičia kintamųjų, esančių už jos ribų. Priskyrimo veiksmai pakeičia tik “lokalius" kintamuosius - esančius funkcijos viduje. Tai natūraliai apsaugo nuo netikėtų nesusipratimų (pvz., jei kelios funkcijos naudotų tą patį kintamojo vardą).
Detaliau tai galite pamatyti 6-tame žingsnyje ("Step 6 of 8"): matosi du skirtingi kintamieji value: vienas square funkcijoje, o kitas už funkcijos ribų - “globalioje” programos srityje.
x = "outer"
def xReplace(value):
x = value
xReplace("inner")
print(x)x = value veikia tiktai viduje esantį kintamajį x. Išorėje esantis globalus kintamasis x nebuvo pakeistas. (taigi, funkcija xReplace yra bevertė.)Į kintamųjų galijimo sriį ("variable scope") panaši sąvoka yra "namespace" (vardų galiojimo sritis). Jos pagalba nurodoma, kad kintamasis yra iš konkrečios programos dalies -- iš kažkurio importuoto modulio. Pvz., jei importuojame paketą math, kuriame yra kintamąsis x, jis nepersidengia su mūsų programos kintamuoju x, nes pasiekiamas „per tašką“ math.x
Sričių taisyklė: pirmiau žiūrim viduje, o paskui - išorėn
Kartais prireikia funkcijos viduje panaudoti globalius kintamuosius. Pvz., programos pradžioje priskiriame kintamajam reikšmę, ir norime, kad mūsų funkcijos ją žinotų - matytų.
Funkcijoje nebuvo kintamojo favouriteTopping, tačiau klaida neįvyko. Pitonas kintamuosius peržiūri pagal tokią tvarką: visų pirma ieško lokalaus kintamojo, o po to -- globaliai galiojančio. Mūsų atveju programa rado favouriteTopping globalioje srityje.
![]() | Aukščiau esantys pavyzdžiai su orderPizzas ir xReplace yra beveik identiški. Kodėl xReplace kintamasis x yra lokalus, o orderPizzas atveju favouriteTopping - lieka globalus? Pitone galioja taisyklė: jei funkcijoje kintamajam priskiriama reikšmė, tai jis standartiškai padaromas lokaliu (kad nebūtų konfliktų su kitom programos dalimis). Tai pati dažniausia priežastis klaidos: UnboundLocalError: daugiau apie tai [1, 2] oficialioje Pitono dokumentacijoje. |
Funkcijos argumentai yra visada laikomi naujais lokaliais kintamaisiais. Tai pailiustruoja šis neveikiantis kodas ( jis bando kintamąjam g priskirti reikšmę 0).
Situacija su kintamųjų galiojimo sritimi galima palyginti su gyventojų vieša ir privačia erdve: tai, kas vieša (globalu) - žinoma visiems, o kas privatu (lokalu) - nežinoma už namo sienų.
global'ūs pakeitimai
Aukščiau aprašytas princiapas tinka 99% atvejų. Tačiau, kartais patogu globalų kintamąjį pakeisti funkcijos viduje. Tai galima padaryti naudojant raktažodį global .
Štai aukščiau buvusio xReplace modifikacija: nurodžius, kad kintamasis yra global'us, jo reikšmė pakeičiama iš "outer" į "inner":
Kaip jau minėjome, norint panaudoti globalaus kintamojo reikšmę, nereikia naudoti global. Jis naudojamas tik norint priskirti/pakeisti reikšmes.
P.s.: 13 pamokoje išmoksite apie sąrašus -- jų pertvarkymus funkcijojse galima daryti be global, ir jie išliks, nes sąrašų saugojimas atmintyje įdomesnis negu paprastų kintamųjų ;).




