Am văzut până acum că trebuie să declarăm variabilele înainte să le folosim. Dar, oare le putem folosi oriunde? Nu chiar...
Să considerăm următorul program:
1 2 3 4 5 6 7 8 9 10 |
def test(): n = 2457 if n % 2 == 0: print("Număr par") else: print("Număr impar") test() print(n) |
Poate ne-am aștepta ca totul să fie în regulă, dar nu e așa. Primim o eroare care ne spune că variabila n din linia 10 nu este cunoscută. Ar părea că am declarat această variabilă în linia 2. Dar, această declarație a fost făcută în interiorul funcției test și e valabilă doar acolo.
Spunem că o variabilă este vizibilă doar acolo unde este declarată. Evident, ea poate fi folosită doar acolo unde este vizibilă. Spunem că locul în care poate fi văzută o variabilă este domeniul de vizibilitate al variabilei.
Am văzut că o variabilă declarată într-o funcție nu poate fi utilizată în afara funcției respective. Dar, e mai complicat decât atât. De fapt, o variabilă este vizibilă doar în interiorul blocului de instrucțiuni în care a fost declarată. Următorul program nu este nici el corect:
1 2 3 4 5 6 7 |
n = 2457 if n % 2 == 0: k = 47 print(k % 10) print(k) |
De data aceasta eroarea apare în linia 7, deși variabila k a fost declarată în linia 4.
Dacă o variabilă nu este vizibilă într-un anumit bloc de instrucțiuni, o putem declara. Ar putea părea că am declarat o variabilă de mai multe ori, dar trebuie să luăm în considerare faptul că domeniile de vizibilitate sunt diferite. Următorul program este corect:
1 2 3 4 5 6 7 |
n = 2457; if n % 2 == 0: k = 47 print(k % 10) else: k = 13 print(k % 2) |
Practic avem două variabile k; prima există în blocul de instrucțiuni dintre liniile 2 și 4, iar a doua în blocul dintre liniile 5 și 7.
Trebuie să avem grijă ca domeniile de vizibilitate a două variabile cu același nume să nu se suprapună. De cele mai multe ori nu este permis; uneori este posibil, dar trebuie să fim atenți.
Să vedem acum un exemplu mai interesant:
1 2 3 4 5 6 |
def test(n): n = 47 print(n) test(2457) |
Nu este corect nici așa ceva; parametrul n este vizibil în cadrul funcției test, deci corpul acestei funcții nu poate conține o declarație a unei variabile cu același nume fiindcă domeniile de vizibilitate s-ar suprapune.
Am văzut că, dacă au domenii de vizibilitate diferite, două variabile sunt diferite chiar dacă au aceeași denumire. Să vedem mai exact ce înseamnă acest lucru:
1 2 3 4 5 6 7 8 |
def test(): n = 47 print(n) n = 2457 test() print(n) |
Avem o variabilă n a cărei valoare este 2457. Apelăm funcția test; în cadrul acesteia avem o altă variabilă n cu valoarea 47 și scriem valoarea acesteia. Execuția funcției se încheia și urmează scrierea variabilei n; se va scrie 2457, fiindcă variabila din interiorul funcției nu este vizibilă în afara funcției și atribuirea din linia 2 nu afectează valoare variabilei n de pe linia 6.
Trebuie să reținem faptul că orice instrucțiune care folosește o variabilă o folosește pe cea vizibilă, chiar dacă în alte locuri există variabile cu același nume. Să vedem un exemplu mai interesant:
1 2 3 4 5 6 7 8 |
def test(n): n += 1 print(n) n = 2457 test(n) print(n) |
Vom vedea că în urma execuției instrucțiunii din linia 3, este scrisă valoarea 2458, dar în urma execuției instrucțiunii din linia 8, este scrisă valoarea 2457.
Avem o variabilă n definită în linia 6 și inițializată cu valoarea 2457. Aceasta este transmisă ca argument al apelului funcției test. În linia 2 valoarea parametrului funcției test este incrementată. Dar, deja avem o altă variabilă (parametrul); incrementarea se aplică doar asupra ei. Noua valoare este tipărită și execuția funcției test se încheie. Variabila definită în linia 6 nu a fost afectată de incrementarea din linia 2; ca urmare, în momentul executării instrucțiunii din linia 8, valoarea sa este tot 2457.
Există mecanisme prin care modificările aduse unui parametru al unei funcții să nu se piardă în momentul în care se încheie execuția funcției respective, dar vom reveni asupra acestui aspect la momentul oportun.
Situația este aceeași dacă variabila transmisă ca argument ajunge să devină un parametru cu alt nume. Efectul execuției următorului program este același:
1 2 3 4 5 6 7 8 |
def test(k): k += 1 print(k) n = 2457 test(n) print(n) |
Va urma
Am văzut până acum cum putem avea instrucțiuni care să se execute sau nu (folosind instrucțiuni condiționale). Am văzut de asemenea cum putea avea instrucțiuni care sunt executate de mai multe ori (folosind apeluri multiple de funcții). Dar, trebuie să efectuăm câte un apel de fiecare dată când doream să executăm o funcție. În următorul episod vom introduce conceptul de buclă; vedea cum vom putea executa anumite instrucțiuni de mai multe ori, atâta timp cât o anumită condiție este îndeplinită.