Parametri i argumenti funkcija - ★★ Fog Developer ★★

Novo

6/recent/ticker-posts

Parametri i argumenti funkcija

9.1 Parametri i argumenti funkcija

Ako si se malo više udubio u razmišljanje koje sam ti zadao malo pre, shvatio si da mi u funkciju „šaljemo“ nešto, i na taj način komuniciramo sa njom – i to tako što to nešto strpamo između zagrada prilikom pozivanja funkcije. To nešto se naziva argument (ili argumenti, ako prosleđujemo više vrednosti u jednom pozivu funkcije) funkcije.
Ali šta se dešava ovde?
>>> def moj_broj(): 
...     print(5) 
... 
>>> moj_broj(6) 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
TypeError: moj_broj() takes no arguments (1 given) 
>>> 
Opet ista greška koju smo dobili i ranije. Zašto?
Prosto: zato što prilikom definisanja funkcije možemo (ako želimo da funkcija „komunicira“ sa ostatkom programa) da definišemo i njene parametre, koji su u suštini samo promenljive koje će da „prihvate“ vrednosti koje prosleđujemo toj funkciji kao argumente! Ovo radimo isključivo zbog toga da bi definisana funkcija mogla da radi nešto sa tim vrednostima upotrebom imena tih promenljivih. Iz toga sledi da su parametri promenljive, ALI takve promenljive koje smo definisali samo za funkciju, i koje će nastati kada smo pozvali funkciju i postojaće kada funkcija radi nešto, a nestaće kada i funkcija prestane sa radom. Konfuzno? Nije, sada ću ti polagano objasniti, krećemo od definisanja parametara.
Definisanje parametara funkcije se vrši tako što ih navodimo u zagradama prilikom definicije funkcije, i, ukoliko želimo da ih bude više, odvajamo ih sa zarezima:
def ime_funkcije(ime_prvog_parametra, ime_drugog_parametra):
    telo_funkcije
Kada smo tako definisali parametre (i funkciju) u telu funkcije možemo koristiti ime_prvog_parametra i ime_drugog_parametra za bilo kakav rad koji nam je potreban!
>>> def funkcija(prvi_parametar, drugi_parametar): 
...     print(prvi_parametar) 
...     print(drugi_parametar) 
... 
>>> funkcija(6, 'bajka za laku noć') 
6 
bajka za laku noć 
>>> 
Dokaz da parametri ne postoje izvan funkcije:
>>> print(prvi_parametar) 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
NameError: name 'prvi_parametar' is not defined 
>>> 
Ups... Pa kako nije definisan? Pa i nije – definisan je i postoji jedino za našu funkciju, ne i za naš program!
>>> funkcija('Čemu ovo služi?', 'a uz to i ne radi!') 
Čemu ovo služi? 
a uz to i ne radi! 
>>> funkcija('Čemu ovo služi?', 'a uz to i ne radi!', 'ipak radi?') 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
TypeError: funkcija() takes exactly 2 positional arguments (3 given) 
>>> 
Uh, šta se desilo?
Kada pozivamo funkciju, mi moramo da joj prosledimo vrednosti argumenata na isti način na koji smo definisali parametre. U funkciju uvek možemo da pošaljemo onoliko argumenata, koliko smo parametara definisali, takođe, ukoliko radimo na ovaj način, argumenti moraju biti raspoređeni na isti način na koji smo rasporedili parametre, u suprotnom dobijamo neočekivan rezultat! Na primer:
>>> def pitalica(pitanje, ime): 
...     k = input(pitanje) 
...     print(ime, 'voli', k,'!') 
... 
>>> pitalica('Šta najviše voliš? ', 'majmun') 
Šta najviše voliš? ništa 
majmun voli ništa ! 
>>> pitalica(2, 'majmun') 
2? 
majmun voli ? ! 
>>> 
Mala napomena za korišćenu terminologiju koja može da izazove haos u tvojoj glavi - imena koje stavljamo u zagrade prilikom definisanja funkcije se zovu parametri dok vrednosti koje šaljemo u tu istu funkciju prilikom njenog pozivanja, se nazivaju argumenti. Evo ti slikovito, možda ti i pomogne:
# definisanje funkcije
def funkcija(parametar1, parametar2):
    telo_funkcije

# Pozivanje funkcije
funkcija(argument1, argument2)
Ako ti još nije jasno na šta mislim, zamisli sledeći primer: ti si kapetan svemirskog broda (tj. ti si glavni program), primećuješ neprijateljski brod na koordinatama 86 – 67. Sa tim argumentom u rukama pozivaš raketno odeljenje (funkciju) da ispali fotonsko torpedo na zadatu lokaciju. Raketno odeljenje je od tebe primilo parametre za ciljenje mete i ispalilo je torpedo. Nadam se da je to sad malo jasnije, iako, moram da ti priznam, ukoliko si stvarno (bio) kapetan tog broda, da sam ja, kao tvoj sistem administrator i opaki kladioničar, izmenio glavni program brodskog kompjutera da mi prikazuje trenutne rezultate košarkaških utakmica. Mislim da nije moja greška što si ti mislio da su to neke nevažne koordinate, pa se ni ne osećam odgovorno što ste ispalili torpeda u pogrešnom pravcu, te vas je neprijateljski brod razložio na protone, neutrone i elektrone. Budući da ovo čitaš, znači da si živ i zdrav u nekoj drugoj dimenziji, pa ako ti je za utehu – taj tiket mi je prošao...
Šalu na stranu... Sada kada smo „potkovani“ sa znanjem, hajde da to znanje iskoristimo u neke pametne svrhe...
Na primer želimo da napišemo program koji će da šalje novogodišnje čestitke našim prijateljima. Želimo da čestitka bude 48 karaktera široka, uokvirena sa zvezdicama (*) i da u njoj stoje reči Pozdrav, pa ime prijatelja i na kraju „Sretna Nova Godina!“. Krećemo tako što kreiramo skriptu ng_pozdrav.py:
#!/usr/bin/env python3 

################################ 
# Kreira novogodišnju čestitku # 
################################ 

def prikazi(ime): 
    sablon = '*{:^46}*' 
    print('\n\n') 
    print('*' * 48) 
    print(sablon.format(' ')) 
    print(sablon.format('Pozdrav!')) 
    print(sablon.format(' ')) 
    print(sablon.format(ime)) 
    print(sablon.format(' ')) 
    print(sablon.format('Srećna Nova Godina!')) 
    print(sablon.format(' ')) 
    print('*' * 48) 
    print('\n\n') 

def glavni(): 
    while True: 
        print('Kreiraj čestitku za Novu godinu!') 
        ime = input('Unesi ime i prezime osobe kojoj šalješ pozdrav:\n>>> ') 
        prikazi(ime) 
        dalje = input('Ako želiš da nastaviš da kreiraš pozdrave, kucaj bilo šta\nа аko ne želiš samo enter za izlaz \n iz programa.\n>>> ') 
        if not dalje: 
            break 

glavni()
Auh... zabole me glava....
Ne treba da te boli, ovaj primer ti je prilično bitan jer u sebi sadrži koncepte koje treba da razumeš, da bi uopšte i mogao da se baviš programiranjem.
Prvi pregled: Pogledaj program dobro. Od koliko linija koda se on sastoji?
Ako si dobro prebrojao, ovaj program se sastoji samo od jedne linije koda! Znači, sve što ovaj program radi je to da – poziva funkciju glavni() - i to je cela filozofija! Ako, ipak, nisi brojao dobro, i ne vidiš o čemu pričam – ova linija koda se nalazi na samom dnu skripte. 
Drugi pregled: Zašto se taj kod nalazi na dnu? Pa zato što funkciju možemo pozvati samo kada ona negde postoji, tj kada je definisana! Python kreće od vrha, vidi definisanje funkcije prikazi() (to je definicija, pamtim njeno ime, preskačem ovaj kod), zatim nailazi na definiciju glavni() (to je definicija, pamtim ime, preskačem ovaj kod), i na kraju dolazi do poziva funkcije glavni() (aha, ovo je poziv funkcije, zapamtio sam njeno ime, zato idem sada da izvršim njen kod). Ako je nismo definisali pre pozivanja, već negde ispod, Python će da se buni (programer mi govori da pozovem nešto na šta još nisam naleteo... bolje da odbijem saradnju odmah....).
Eh, ako i ti kao čitalac nekog programa budeš pratio Pythonovu filozofiju, nećeš daleko dogurati. Do sada ti je najlogičnije bilo da programe čitaš od vrha prema dole, no pojava funkcija, ukoliko i dalje praktikuješ takav rad, ti samo izaziva konfuziju. Zato imam mali savet za tebe. Kada otvoriš neki Python program da bi ga analizirao, kreni da ga čitaš odozdo! Evo na primer ovaj gornji. Prva linija na koju si naleteo je glavni(). Aha, to je neka funkcija, nalazi se negde iznad, zatim je nađeš iznad, pa čitaš njen kod, i tako redom dalje.
Treći pregled: Možda misliš da sam namerno ovaj program napisao ovako i tu si sasvim u pravu! A uskoro ćeš i ti da tako pišeš. Zašto: Pa, suštinski, ti funkciju možeš da definišeš bilo gde u svom programu, čak i u nekoj drugoj funkciji.... Zamisli ti sad da napraviš „paprikaš“ od 150 funkcija, koje su razbacane kako-gde koja treba. U takvom programu se verovatno ni ti sam ne bi snašao, a kamoli neko drugi. Zato postoji konvencija da sve što se definiše, a potrebno je za izvršavanje nekog koda se piše na vrhu skripte, sam program se piše nakon svih definicija, što ga samim tim, automatski smešta pri dnu skripte. Ako pogledaš strukturu programa, sasvim je lako snaći se, gore definicije, dole rad.
Četvrti pogled: Ali zašto sam ceo program strpao u jednu funkciju glavni()? I to je konvencija, zapravo, nije, obično se ta funkcija naziva main(), ali eto ja joj ime prevedoh na naš jezik. No pitanje je zašto? A na to pitanje ćeš znati odgovor malko kasnije, sada ću ti samo nagovestiti – možda mi i ne želimo da pokrenemo ovaj program kao takav, možda ovaj program treba da pokrene – neki drugi program?
Peti pogled: Funkcija glavni() je u sebi pozvala funkciju prikazi(), zar to može tako? Hehe, pa u Pythonu sve može! Ovo je glavna stvar, iz funkcije možeš pozvati bilo koju drugu funkciju, kao što bi to i obično uradio u svom programu. Čak, šta više funkcija može u nekim slučajevima da pozove i samu sebe i to se naziva rekurzija! Primer:
>>> def recur(x): 
...     if x == 0: 
...             print(x) 
...     else: 
...             print(x) 
...             x -= 1 
...             recur(x) 
... 
>>> recur(0) 
0 
>>> recur(5) 
5 
4 
3 
2 
1 
0 
>>> 
Moj ti je savet da za početak izbegavaš rekurziju, jer slučajno možeš ubaciti program u beskonačno pozivanje funkcija, što će na kraju rezultirati krahom programa. Primer je ista ova funkcija slučajno pozvana sa negativnim brojem kao argumentom:
>>> recur(-1)
...
  File "<stdin>", line 7, in recur 
  File "<stdin>", line 7, in recur 
  File "<stdin>", line 7, in recur 
  File "<stdin>", line 7, in recur 
  File "<stdin>", line 7, in recur 
  File "<stdin>", line 5, in recur 
RuntimeError: maximum recursion depth exceeded while calling a Python object 
>>> 
Umesto nekog lepog rezultata, dobili smo mnogo gadnih poruka o greškama! Zato, pažljivo u ovoj avanturi!

9 Funkcije Indeks 9.2 Lokalne
promenljive

Постави коментар

0 Коментари