Fajlovi

12.2 Fajlovi 

Problem: Već si mi pričao koliko su fajlovi važni za računar. Da li ću na ovom mestu naučiti kako da kreiam fajlove koje bi računar koristio za svoje potrebe?
Odgovor: Tvoje pitanje je dosta široko. U neku ruku odgovor je – da, naučićeš da radiš sa fajlovima u Pythonu, ali i - ne jer tvoj računar koristi toliko različitih fajlova za različite poslove, da bi nam ogromna enciklopedija bila mala da objasnimo sve moguće kombinacije.
A što se ja zamajavam sa ovim?
Pa, ne zamajavaš se.... Suština programiranja je konstantno učenje novih stvari. Ukoliko ti je problem da napraviš neki fajl, na primer html (za web stranicu), ti ćeš potražiti negde kako taj fajl treba da izgleda, a potom ćeš moći u Pythonu da ga generišeš, bez da se preterano mučiš. Znači – učenje je ključna reč za svaki posao koji želiš da obaviš! Zato ćemo odmah i da krenemo sa njim.
Kao i kod bilo čega drugog, u Pythonu se rad sa fajlovima (otvaranje i čitanje ili pisanje) postiže kreiranjem nekog objekata (tzv file objekta, koji nije file klase, jer ta klasa ne postoji, već je objekat klase koja „reguliše“ ulaz/izlaz). Kada u svom programu imamo takav objekat, možemo koristiti njegove metode, tipa read() - koja čita celokupan fajl , readline() - koja čita jednu liniju u jednom trenu ili write() - koja upisuje nešto u fajl. Zanimljivost kod fajl objekata je ta da njihova sposobnost da čitaju ili pišu u samom fajlu, koji se nalazi negde na hard disku, zavisi od režima rada, koji određujemo prilikom kreiranja ovog objekta. Takođe je važno da istaknem da na kraju rada ovog objekta, u suštini, kada završimo sve potrebne manipulacije sa tom datotekom, moramo da pozovemo close() metod, kako bi kazali Python-u da smo završili sa korišćenjem tog objekta. Eh, sad. U suštini i ne moramo, jer Python ima dobar sistem za „prikupljanje našeg smeća“ koje zaboravimo u memoriji računara, koji se pokreće nakon izvršavanja našeg programa, ali šta ako, u toku rada, u istom programu, pokušamo da kreiramo drugi fajl objekat koji izvršava neke druge radnje nad datotekom koja je već prosleđena i zauzeta sa nekim trećim fajl objektom? Rezultat može biti neočekivan, zato – ništa ne prepuštajmo slučaju – zapamti da na kraju rada sa fajl objektom uvek pozoveš close()!
Budući da je sve ovo „suva“ teorija, hajde da pređemo na praksu.
No, pre nego što krenemo u „akciju“ mala napomena. Budući da ćemo da kreiramo fajl negde na tvom hard disku, bilo bi poželjno da interaktivni prompt pokreneš u nekom folderu koji je prazan ili u kom možeš lako da nađeš ovaj fajl... Tako, na primer ja sam uradio sledeće:
lenj@lenj-OEM:~$ cd ~/Desktop/Novi\ rad/Test\ Kodovi/12.Poglavlje 
lenj@lenj-OEM:~/Desktop/Novi rad/Test Kodovi/12.Poglavlje$ python3
Python 3.3.2+ (default, Oct  9 2013, 14:56:03) 
[GCC 4.8.1] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> 
Jednostavno sam sa cd komandom u svom šelu „otišao“ na željeno mesto i odatle pokrenuo Python. Ti uradi nešto slično, ali ukoliko pokreneš samo Python prompt bez menjanja direktorijuma, najverovatnije ćeš kreirati fajlove na podrazumevanoj lokaciji tvog operativnog sistema.
Sada kada smo pokrenuli prompt, možemo li da nastavimo?
Prvo nam treba nešto što želimo da „upišemo“ u fajl. Hajde da napišemo neku pesmu, i da je dodelimo nekoj promenljivoj:
>>> moja_pesma = '''Kada svetlost obiđe 
... u tvom malom oku 
... svoj poslednji krug 
... iznad nezahvalne zemlje. 
... 
... I kada se digne tama 
... iz debelog sna, 
... da naplati svoj 
... kamatom natopljeni dug. 
... 
... Ti ne daj da tvoja mala nada 
... ostane, bez sveće, sama.... 
... postani joj, u tom teškom boju 
... za ljubav, najbolji drug. 
... 
... A, pogledaj, u svoju torbu 
... malo i skriveno, oružije je tu. 
... Python se zove, pa sa njim 
... Nada i Ti - zajedno, 
... izgradite Vaš jedini put.''' 
>>> 
Heh, nije loše? Mala napomena za tebe. Ljudi koji se bave programiranjem su često izloženi velikom psihičkom naporu – jednostavno tražiti rešenja za mnoge probleme i nije tako jednostavno. Pogotovo što se na takvom „klizavom putu“ može svašta saznati, i u najgorem slučaju – otuđiti od ljudi ili tzv „izgaranje“ - razočaravanje u svoj život i posao. Da bi ljudi koji se bave ovim zanimanjem imali kontakt sa „nesavršenom“ realnošću (jer za razliku od života u ljudskoj zajednici, računari rade baš ono i onako kako je predviđeno, nikada ne lažu, ne varaju i sl, zapravo – računare možeš kontrolisati, ali svoju okolinu – teško, ukoliko nisi ono što se kaže - „đubre od čoveka“), moraju da imaju neki hobi – pa tako, pisanje pesama ili priča, sviranje instrumenata, sport – u glavnom, nezaobilazno je da se, pored programiranja, baviš i nekim kulturnim stvarima, koje ti postaju „ventil“ za probleme iz tvoje privatne sfere života. Ja na primer pišem pesme i priče, koje možeš pročitati na mom blogu.
A sada se vraćamo iz umetničkog u programerski deo ovog tutorijala.
Da bi smo otvorili neku datoteku, koristimo ugrađenu funkciju open(), u kojoj navodimo ime fajla i način (ili, drugim rečima, režim) na koji želimo da ga otvorimo. Režim može biti: čitanje ('r' – skraćenica od engleske reči read), pisanje ('w' - write) ili dodavanje ('a' - append). Isto tako, mi imamo mogućnost da specifiziramo da li želimo da se to čitanje, pisanje, ili dodavanje odvija u tekstualnom režimu ('t' – text, standardan, i samim tim, podrazumevan za rad sa „običnim“ fajlovima) ili u binarnom modu ('b' – binarni fajlovi, nisu tema ovog tutorijala). Ti zapravo imaš mnogo više opcija koje su ti na raspolaganju, pa pokreni help(open) da ih upoznaš. Podrazumevano, fajl otvoren sa open() će da bude 't' - tekst fajl i otvara se u 'r' - režimu za čitanje.
Za naš primer, gde želimo da sačuvamo ovu pesmu, prvo ćemo otvoriti datoteku u režimu upisivanja teksta ('w'), a zatim ćemo koristiti write() metod, da upišemo pesmu u željenu datoteku, a zatim, naravno, moramo da је zatvorimo sa close(). Pa da vidimo kako to izgleda:
>>> fajl = open('Vesela pesma.txt', 'w') 
>>> fajl.write(moja_pesma) 
410 
>>> fajl.close() 
>>> 
Datoteku sam nazvao Vesela pesma.txt, i ona će se nalaziti u trenutnom folderu u kome radim. Mogao sam navesti i neku putanju sa željenim imenom fajla, tada bi se fajl kreirao na naznačenom mestu.
Obrati pažnju na sintaksu write() metode. Ona se primenjuje na fajl objektu, a prosleđuje joj se neki sadržaj. U interaktivnom promptu smo dobili i odgovor koliko bajtova je upisano u fajl. Ukoliko ovu metodu koristimo iz skripte, nećemo dobiti ovaj podatak.
No, na ovom mestu postoji mali problem za nas, koji nismo sa engleskog govornog područja, ovi primeri neka ostanu napisani na ovaj način, jer ćemo se sa problemom susresti za koji tren. Slobodno možeš da „priviriš“ i vidiš o čemu se radi, da te ne bi iznenadila neka greška (ukoliko je na ovom mestu susretneš, što je veoma verovatno, ukoliko si korisnik Windows operativnog sistema).
Sledeće što želimo da uradimo je, što je i sasvim logično, da opet otvorimo isti taj fajl, da bi smo ga pročitali. Sada znamo da ne treba da navodimo režim jer je podrazumevano: "pročitaj tekst fajl".
>>> pesma = open('Vesela pesma.txt') 
>>> 
Uh? Pa gde je pesma?
Pesma je u fajlu. U suštini, mi ovom komandom pripremamo fajl za čitanje, koje mora doći sledeće, i nije baš jednostavno.
Da bi smo pročitali ovaj fajl, mi moramo „proći“ kroz svaku liniju koju sadrži, i to radimo pomoću readline() metode. U većini slučajeva mi nećemo znati koliko fajl sadrži linija, zato je pametno da se čitanje odvija unutar neke petlje. Metoda readline() nam daje kompletnu liniju, uključujući i znak za prelazak u novi red, koji se nalazi na njenom kraju. Znaćemo da smo došli do kraja fajla, kada nam readline() vrati prazan string, i to treba da nam bude znak za prekid petlje.
Mi želimo i da prikažemo tekst – za to će da nam posluži naš stari drugar – funkcija print(), ali, podrazumevano, print(), sem što nam prikazuje tekst, automatski prelazi u novi red na ekranu. Da bi smo sprečili takvo ponašanje (prelazak u novi red), prosleđujemo joj argument end = ' ' , jer na kraju svake linije koju čitamo iz datoteke, već postoji znak za prelazak u novi red. I naravno, ne smemo zaboraviti da zatvorimo datoteku sa close():
>>> while True: 
...     stih = pesma.readline() 
...     if len(stih) == 0: 
...             break 
...     print(stih, end = '') 
... 
Kada svetlost obiđe 
u tvom malom oku 
svoj poslednji krug 
iznad nezahvalne zemlje. 

I kada se digne tama 
iz debelog sna, 
da naplati svoj 
kamatom natopljeni dug. 

Ti ne daj da tvoja mala nada 
ostane, bez sveće, sama.... 
postani joj, u tom teškom boju 
za ljubav, najbolji drug. 

A, pogledaj, u svoju torbu 
malo i skriveno, oružije je tu. 
Python se zove, pa sa njim 
Nada i Ti - zajedno, 
izgradite Vaš jedini put.>>> pesma.close() 
>>> 
Ups...
Ah, primetio si. Prompt je ostao „zaglavljen“ nakon poslednjeg stiha. U interaktivnom promptu nije problem, dovoljno je jednom pritisnuti enter, pa da se pređe u novi red, mada sam ja gore samo nastavio sa radom kao da se ništa ni nije desilo. Ovo „čudno“ ponašanje nije ni najmanje „čudno“. Desilo se baš zbog argumenta end = '' funkcije print() - kada je petlja završila sa čitanjem fajla, nigde nismo naveli da želimo da nam program nastavi iz novog reda, zato on nastavlja tamo gde je i stao, tj, na kraju poslednjeg reda.
Ovde to i nije problem, ali, ukoliko radite nešto ozbiljno, ne zaboravi da u svojoj skripti staviš još jednu praznu funkciju print() posle petlje, jer će ona da natera program da pređe u novi red, u suprotnom, korisnici tvog programa će pomisliti da sa njim nešto nije u redu, i da ne radi kako treba, iako je u pitanju samo estetika.
Sada možeš da se uveriš da si zaista i kreirao neki fajl, tako što ćeš proveriti sadržaj fajla „Vesela pesma.txt“. Evo ga moj fajl:
Sada kada znaš kako se prave i čitaju fajlovi, sem za ovake proste stvari, imaš li ideju kako to iskoristiti?
Pogledaj moju:
>>> funkcija = ''' 
... def prikaz(): 
...     ime = input('Kako se zoveš? ') 
...     print('Zdravo,', ime, '!') 
... ''' 
>>> fajl = open('zdravo.py', 'w') 
>>> fajl.write(funkcija) 
75 
>>> fajl.close() 
>>> import zdravo 
>>> zdravo.prikaz() 
Kako se zoveš? Bond, Džejms Bond! 
Zdravo, Bond, Džejms Bond! ! 
>>> 
Budući da znam kako se pišu funkcije, i kako se importuju moduli, ja sam iskoristio svoj program da sam napravi modul za neke svoje potrebe, a zatim i da ga izvrši!
Zamisli programe koji mogu sami da se popravljaju, nadograđuju i slično, zamisli programe koji kreiraju druge programe, zamisli....Ma... mogućnosti su ti neograničene – tvoja mašta može – svašta!

12.1 Korisnički
unos
Indeks 12.3 Pickle

Коментари

Popularno

Tehnički problemi (i ostala tehnička čudesa) u najavi (i u bliskoj istoriji)

Izvršavanje Python programa

Izbor uređivača teksta (Editora)

Vredela si svakoga stiha

Kreiranje izvorne datoteke

Prevelika očekivanja

Strip o Brus Liju?

Matematički izrazi (ekspresije) u naše programu

Parametri i argumenti funkcija