Moduli

10 Moduli 

Problem: Ja znam kako mogu da više puta koristim neku funkciju u jednom programu. Ali to je, hmmm, bezveze i beskorisno. Ja opet moram, tu istu funkciju da copy-paste-ujem u neki drugi program, ukoliko mi i tamo treba. Nepraktično! Ako želim da nanovo koristim svoje funkcije u nekim drugim programima koje pišem, ima li neko praktičnije rešenje?
Odgovor: Ima! Odgovor leži u nazivu modul. Šta je modul? Pa – modul je jednostavno mesto u koje smo „strpali“ sve ono što nam je važno za neki program. Budući da je to mesto nezavisno od našeg programa, verovatno će ti na pamet pasti niz pitanja, od kojih su najvažnija:
  1. Kako naš glavni program „komunicira“ sa modulom, ili, drugim rečima, kako iz programa pristupiti stvarima definisanim u modulu?
  2. Gde čuvati module, kako bi svi naši programi mogli da komuniciraju sa njima?
  3. Kako se uopšte prave moduli?

Prvo ću krenuti od ovog poslednjeg pitanja, jer je osnova za dalji razgovor na ovu temu.
Kako se pravi modul? Nećeš mi verovati, ali svaka skripta koju si do sada napisao i sačuvao negde na hard disku je – modul!
Čekaj, ne razumem? Ajde daj mi neki tehnički detalj, ovako „laički“ je prilično nerazumljivo.
Dobro, kad baš tražiš. Postoji mnogo različitih metoda za pisanja modula, ali je najjednostavniji da napravimo „skriptu“ čije ime se završava sa ekstenzijom .py, u kojoj bi „ubacio“ sve funkcije i promenljive koje su potrebne tvom programu. 
U Pythonu postoje i druge metode, kao na primer, da napišeš modul u nekom programskom jeziku. Na primer, možeš napisati potreban modul u C programskom jeziku, i, potom, kada ga kompajliraš, možeš da ga koristiš u svom Python programu. 
A sad zanimlčjivost: tvoji moduli mogu da budu korišćeni i od strane nekih drugih programa, kako bi proširio taj program sa funkcionalnostima definisanim u modulu. Zapravo, to je način na koji koristimo Python-ove standardne biblioteke. 
Biblioteke? Zar ću u Pythonu morati da čitam? Jao... Znao sam da ćeš me uvaliti u nešto....
Čekaj malo.... To su Pythonove biblioteke – tj, mesta na kojima se nalaze „knjige“ (hehehe, u stvari moduli) koje Python čita. A budući da ih „čita“ Python, i da se nalaze na TVOM računaru, toplo ti preporučujem da ih i ti, makar „prelistaš“.
Ako sam razumeo dobro, ta „standardna biblioteka“ je samo zbirka modula koje ja mogu koristiti u svojim programima, ali – gde je ona?Hteo bih malo da vidim kako pravi programeri pišu svoje programe.
Odlično pitanje! Ali pre nego što ti odgovorim treba da znaš nešto – Python svoje standardne biblioteke automatski pronalazi (videćeš i gde), ali ti kao programer uvek moraš znati koji modul, i kako, da „ubaciš“ u svoj program. I tu leži odgovor na prvo i drugo pitanje.
Prvo što želim da ti praktično pokažem je kako da koristiš module standardnih biblioteka, a zatim ćemo preći i na one koje ćemo sami praviti.
>>> import sys 
>>> 
Kada Python naleti na komandu import, on zna da mi od njega tražimo da „uveze“ neki modul. Ukratko, komanda import je komanda kojom mi „proširujemo“ naš program sa modulima. U ovom primeru, Python je ugledao import sys komandu, koja mu govori da potraži sys modul, i u ovom slučaju, Python zna da je sys jedan od modula iz standardne biblioteke, zatim Python ga nađe i istog momenta izvršava.
Čekaj, Python ovde ništa nije izvršio....
Gledaj, Python će izvršiti (pokrenuti) modul (program) ukoliko u modulu postoji glavni blok, koji će mu to reći, ali ukoliko su u modulu samo funkcije (ili klase koje ćemo kasnije učiti) onda Python i nema šta da izvrši! On će samo da „dobije pristup“ onim funkcijama koje se nalaze „izvan“ našeg programa, tj u samom tom modulu! Jel sad shvataš zašto sam te, u onom primeru, nagovorio da „glavni“ deo programa staviš u funkciju?
Znači, u ovom slučaju, mi smo uvezli sys modul pomoću import naredbe. Suštinski, to znači da smo rekli Python-u da želimo da koristimo konkretno ovaj modul. Modul sys u sebi sadrži funkcionalnosti vezane za Python-ov interpreter i naš operativni sistem.
Kako je Python znao gde se nalazi sys modul, hoću i ja malo da „procunjam“ i vidim kako to izgleda.
Pa jednostavno! Ukoliko posle import naredbe navedemo ime modula koji nije napisan u samom Python-u, i ne nalazi se u trenutnom direktorijumu (u kojem smo izvršili import naredbu), tada će Python da potraži ime tog modula u direktorijumima koji se čuvaju u varijabli koja se zove sys.path. Kada je modul pronađen, on postaje dostupan za korišćenje. Imaj na umu to, da se inicijalizacija modula vrši samo prvi put kada smo uvezli modul u program. Tj. ukoliko je modul neki program, izvršiće se čim Python naleti na njegov prvi import, a ukoliko kasnije pokušamo da ga izvršimo, import naredba nam neće pomoći! Ovo, važi, samo u slučaju kada u modulu nisu samo funkcije, nego i glavni (tj izvršni) deo, tako da, ukoliko u module samo stavljamo funkcije (klase ili promenljive) ne moramo da brinemo o ovoj začkoljici.
No, hajde da ti pokažem to mesto na kompjuteru gde Python „čita knjige“....
>>> import sys 
>>> sys.path 
['', '/usr/lib/python3.2', '/usr/lib/python3.2/plat-linux2', '/usr/lib/python3.2/lib-dynload', '/usr/local/lib/python3.2/dist-packages', '/usr/lib/python3/dist-packages'] 
>>> 
Promenljiva sa nazivom sys.path u sebi sadrži spisak imena direktorijuma iz kojih Python uvozi module. Budući da je ovako malko nepregledno, hajmo da napravimo jedan lepši prikaz ovoga pomoću naše for petlje, koja prolazi kroz listu stvari:
>>> for i in sys.path: 
...     print('Tražim module u:', i) 
... 
Tražim module u: 
Tražim module u: /usr/lib/python3.2 
Tražim module u: /usr/lib/python3.2/plat-linux2 
Tražim module u: /usr/lib/python3.2/lib-dynload 
Tražim module u: /usr/local/lib/python3.2/dist-packages 
Tražim module u: /usr/lib/python3/dist-packages 
>>> 
Sada znaš koja su to mesta u tvom računaru, na kojima se nalaze dragocene biblioteke, koje, sem Pythonu, su i tebi dostupne za čitanje!
Obrati pažnju na to da je prvi string u promenljivoj sys.path prazan! Taj prazan string Pythonu (a i nama), govori da je direktorijum, u kojem je Python i pokrenut, takođe deo putanje u kojoj će se tražiti moduli! To jednostavno znači da će Python prvo uvoziti module koji se nalaze u direktorijumu našeg programa. Što, dalje znači, da ukoliko želimo da NAŠ modul bude dostupan nekom našem programu, dovoljno je da taj modul prebacimo u isti folder u kojem je i naš program. Ako ne želiš da radiš na taj način, moraš da premestiš svoj modul u jedan od direktorijuma koji su navedeni u promenljivoj sys.path. 
Uvek znaj da je trenutni direktorijum, u stvari, direktorijum iz koga je pokrenut program. Da bi saznao trenutni direktorijum u kojem si, možeš koristiti os modul i njegovu getcwd funkciju:
>>> import os 
>>> os.getcwd() 
'/home/lelemud' 
>>> 
Kod tebe će možda biti prikazana neka druga vrednost, ovo samo govori da sam ja pokrenuo Pythonov interaktivni prompt u svome home folderu.
Sada kada znamo sve to, hajde da napravimo malu skripticu, koja će koristiti promenljivu argv iz sys modula, a koju ću za trenutak i da objasnim sačuvaj kao komandna_linija.py:
#!/usr/bin/env python3 

'''Skripta koja pokazuje kontrolu programa preko komandne linije.''' 

import sys 

print('Argumenti koji su prosleđeni programu su: ') 
for i in sys.argv: 
    print(i)
(ovo je samo početna skica, na koju dalje „lepimo“ nešto što smo smislili)
I, ovaj program radi ovo:
./komandna_linija.py neki bezveze argumenti koji kontrolišu program 
Argumenti koji su prosleđeni programu su: 
./komandna_linija.py 
neki 
bezveze 
argumenti 
koji 
kontrolišu 
program 
Kako ovo funkcioniše i šta u stvari ovaj program predstavlja?
Ukoliko u dosadašnjem delu života nisi imao potrebu za pokretanjem računarskih programa koristeći komandnu liniju ovaj program ti može izgledati čudno i strano. No, na velikim serverima, ili iz raznoraznih drugih razloga (kao na primer brzina), postoji potreba da se programi pokreću baš preko komandne linije, najčešće, takvi programi nemaju GUI. Ako program nema GUI, mi ipak moramo na neki način da ga kontrolišemo. I zato, da bi smo podesili određene parametre programa, mi njemu možemo postaviti argumente, koji kontrolišu izvršavanje tog programa. Za neki primer koji će 100%  raditi na tvom računaru, pokušaj:
python3 -h
Kao što vidiš, python3 je ime programa, a -h je argument, koji, neće pokrenuti program, već će nam pokazati dokumentaciju pomoći, tj kako se program koristi i koje mogućnosti imamo.
Sličnom logikom smo se vodili i prilikom pisanja ovog programa – treba da ga pokrenemo, i da mu prosledimo neke argumente. Ali, da bi program kontrolisali pomoću argumenata komandne linije, sam program mora znati koje smo mu mi to argumente zadali! A za to nam, na našu sreću, služi sys.argv promenljiva, koja u listi stringova (liste su detaljno objašnjene u kasnijem poglavlju) čuva sve argumente koje smo prosledili programu.
Napomena: Ako koristiš neki IDE za pisanje i pokretanje svojih Python programa, moraš naći način da pokreneš ovaj program sa argumentima (pretraži menije samog IDE-a koji koristiš). 
U našem primeru mi smo pokrenuli python3 komandna_linija.py neki bezveze argumenti koji kontrolišu program , mi smo pokrenuli program komandna_linija.py, a sve ostalo što smo napisali su argumenti koje prosleđujemo tom programu. Kao što sam ti već rekao, Python čuva argumente komandne linije u sys.argv promenljivoj, i mi je prikazujemo. 
Prilikom izvršavanja mi vidimo sledeće: ime skripte koja se trenutno izvršava je prvi argument u sys.argv listi, a zatim, jedan po jedan, izlistani su svi argumenti koje smo „prosledili“, i to onim redosledom, kojim smo i napisali. Zapamti da Python počinje brojanje od 0, a ne od 1, tako da, u suštini, ime skripte (u našem slučaju komandna_linija.py) ima oznaku sys.argv[0], što ćeš kasnije i saznati šta znači.
Kao što sam ti već i rekao argv je promenljiva u sys modulu! Ona se ne zove sys.argv, već samo argv! Ali, mi smo u svom programu pisali sys.argv. Zašto? Pa zato što se stvarima koje se nalaze unutar modula pristupa na taj način što koristimo oznaku tačka, odnosno, sys.argv – prvi deo je ime modula (u našem slučaju sys) pa zatim ide tačka, pa ime objekta (funkcije, promenljive itd, u našem slučaju promenljiva sa nazivom argv). Tako napisano, jasno ukazuje Pythonu da je ovo ime promenljive koja je deo sys modula, a ne neke druge promenljive koja može da nosi naziv argv. Prednost ovakvog pristupa je da se imena ne kose sa nekom drugim imenima promenljivih koje bi smo koristili u našem programu.  Ukratko, kada smo ovako napisali program, mogli bi smo da u njemu imamo neku našu argv promenljivu, koja ne bi ni na koji način uticala na vrednosti istoimene promenljive iz sys modula.
Ako je to jasno, idemo da „poboljšamo“ naš program, tako da mu možemo proslediti -h, u kom slučaju će nam prikazati pomoć, ili -a, u kom slučaju će nam prikazati sve argumente koje smo mu prosledili!
#!/usr/bin/env python3 

'''Skripta koja pokazuje kontrolu programa preko komandne linije. 
Možete koristiti: 
    -h : prikazuje ovu pomoć 
    -a : prikazuje sve prosleđene argumente 
    -d : prikazuje trenutni direktorijum u kome se nalazimo''' 

import sys 
import os 

def prikaz_h(): 
    '''Prikazuje help.''' 
    print(__doc__) 

def prikaz_a(lista): 
    '''Prikazuje sve argumente.''' 
    print('Argumenti koji su prosleđeni programu su: ') 
    for i in lista: 
        print(i) 

def prikaz_d(): 
    print('Trenutno si u: ', os.getcwd()) 

for i in sys.argv: 
    if i == '-h': 
        prikaz_h() 
    if i == '-a': 
        prikaz_a(sys.argv) 
    if i == '-d': 
        prikaz_d()
U ovom programu smo definisali funkcije koje govore šta želimo da se desi, ukoliko prosledimo određene parametre našem programu. Probaj malo, igraj se:
./komandna_linija.py -h 
Skripta koja pokazuje kontrolu programa preko komandne linije. 
Možete koristiti: 
    -h : prikazuje ovu pomoć 
    -a : prikazuje sve prosleđene argumente 
    -d : prikazuje trenutni direktorijum u kome se nalazimo 
./komandna_linija.py -d 
Trenutno si u:  /home/lelemud/Desktop/Novi rad/Test Kodovi/10.Poglavlje 
./komandna_linija.py -d -h -a jjhl kkk 
Trenutno si u:  /home/lelemud/Desktop/Novi rad/Test Kodovi/10.Poglavlje 
Skripta koja pokazuje kontrolu programa preko komandne linije. 
Možete koristiti: 
    -h : prikazuje ovu pomoć 
    -a : prikazuje sve prosleđene argumente 
    -d : prikazuje trenutni direktorijum u kome se nalazimo 
Argumenti koji su prosleđeni programu su: 
./komandna_linija.py 
-d 
-h 
-a 
jjhl 
kkk 
Vidimo da program radi za sve prosleđene kombinacije. Pokušaj za domaći da ga proširiš, kako bi imao još neke funkcionalnosti. Takođe, malo „obiđi“ standardnu biblioteku i pročitaj nešto po svom izboru.

9.10 Rezime Indeks 10.1 Kompajlirani
.pyc fajlovi

Коментари

Popularno

Audacious - program za slušanje muzike

LibreOffice Calc - program za izradu tabela

Brasero - program za rezanje CD-ova

Bekstvo iz Titela

Minitube - program za praćenje YouTube sadržaja

Idemo

Kako blokirati neželjene oglase koje AdSense pokazuje na Vašoj web lokaciji

Bezimena

Pozadina Bekstva iz titela

Pažljivo sa MS Word dokumentima koje primate putem elektronske pošte