Izrada sopstvenih modula - ★★ Fog Developer ★★

Novo

6/recent/ticker-posts

Izrada sopstvenih modula

10.4 Izrada sopstvenih modula 

Sada kada znaš da je kreiranje naših ličnih modula lako, i da smo, zapravo, mi to radili svo vreme u toku ovog tutorijala, hajde još malo da to provežbamo. No, na samom startu, da se podsetimo: svaki naš Python program je u stvari i modul.
Hajde da „ubacimo“ naše znanje u pogon, sačuvaj pod imenom plava.py:
#!/usr/bin/env python3 

'''Primer koji pokazuje 
"razgovor" između dva modula.''' 

def ime(): 
    print('Zovem se Jelena.') 

__version__ = 'plavuša' 

if __name__ == '__main__': 
    ime() 
    print('I ja sam', __version__, '.')
Ovo gore je „klasičan“ primer jednog modula. Kao što vidiš, u njemu ne postoji ništa posebno niti specijalno, što do sada nismo obradili. Možda te može zbuniti ime __version__, ali to je ime promenljive, koje se često koristi da se označi verzija programa. Počinje sa donjom crtom, zato što je u neku ruku „specijalno“, slično kao i __name__, ali o tome ćemo u narednom delu tutorijala. Ovaj modul možemo pokrenuti i samostalno:
./plava.py 
Zovem se Jelena. 
I ja sam plavuša . 
Vidimo da radi kao i svaki drugi program. Sledeća što ću ti pokazati je kako da koristiš ovaj modul unutar nekog drugog Python programa.
Kao što sam ti već ranije napomenuo, ovaj modul mora biti smešteni u istom direktorijumu kao i onaj program u koji želimo da ga uvezemo, ili u jednom od direktorijuma navedenim u promenljivoj sys.path. Šta to znači? Pa jednostavno, znači da mi naš sledeći program moramo da kreiramo u istom folderu, u kom smo kreirali i plava.py modul.
Krećemo sa drugim modulom koji sačuvaj pod imenom frajer.py (u istom direktorijumu u kom je i plava.py):
#!/usr/bin/env python3 

'''Primer koji pokazuje 
"razgovor" između dva modula.''' 

import plava 
__version__ = 'frajer' 

def razgovor(): 
    print('Ja sam strašan', __version__, '.') 
    print('I pošto mi se sviđa što si', plava.__version__, ',') 
    print('Mogli bi smo da se upoznamo.') 
    print('Kako se zoveš?\n\n') 
    plava.ime()    

if __name__ == '__main__': 
    razgovor()
Što nam daje izlaz:
./frajer.py 
Ja sam strašan frajer . 
I pošto mi se sviđa što si plavuša , 
Mogli bi smo da se upoznamo. 
Kako se zoveš? 


Zovem se Jelena. 
Vidiš da je sve ovo u suštini lako, ono što treba da ti „upadne“ u oči i što treba da primetiš je korišćenje oznake sa tačakom za pristup funkcijama i promenljivima unutar modula. Programski jezik Python ima jednu fantastičnu osobinu, a to je jednostavna upotreba sintakse, koja se ne razlikuje od slučaja do slučaja, već je ista za mnoge različite metode prilikom programiranja, tj ne moramo da lupamo glavom u zid, niti da učimo neke nove i različite načine za rad sa različitim stvarima. 
Ajde sad da napravimo i verziju koja će da koristi komande from i import. Neka to bude program koji opisuje lokalnu besposlenu alapaču, koja zarađuje za život drukirajući svoje komšije tajnim službama. Videćete sada kako je lako da se stavite u njenu kožu. Sačuvaj program pod imenom baba_sera.py u istom folderu kao i prethodna dva modula:
#!/usr/bin/env python3 

'''Primer koji pokazuje 
"razgovor" između dva modula.''' 

from frajer import razgovor, __version__ 
__version__ = 'baba sera' 

def drukanje(): 
    print('Halooo? Dobar dan, ovde', __version__, '.') 
    print('Da vidite kako se današnja omladina pokvareno ponaša!') 
    print('Ali ne brinite, sve sam ih čula, nanu im li njiovu...') 
    print('Pa ću sad da Vam ispričam...') 
    print('Evo šta su pričali pokvarenjaci\n\n') 
    razgovor() 
    print('\n\n') 
    print('Nadam se da ćete učiniti nešto po tom pitanju!') 

if __name__ == '__main__': 
    drukanje()
Što nam daje izlaz:
./baba_sera.py 
Halooo? Dobar dan, ovde baba sera . 
Da vidite kako se današnja omladina pokvareno ponaša! 
Ali ne brinite, sve sam ih čula, nanu im li njiovu... 
Pa ću sad da Vam ispričam... 
Evo šta su pričali pokvarenjaci 


Ja sam strašan frajer . 
I pošto mi se sviđa što si plavuša , 
Mogli bi smo da se upoznamo. 
Kako se zoveš? 


Zovem se Jelena. 



Nadam se da ćete učiniti nešto po tom pitanju! 
Šta je zanimljivo u ovom slučaju? Pa zanimljivost je da smo mi importovali __version__ promenljivu, a zatim smo definisali promenljivu sa istim imenom u našem programu. Tim činom smo u suštini, promenili vrednost promenljivoj __version__ sa stringa 'frajer', na string 'baba sera'. Ali, čekaj, kada smo pozvali funkciju razgovor() koja se nalazi u modulu frajer.py, koja za svoj rad prikazuje promenljivu __version__, zašto ona nije prikazala string 'baba sera', već je prikazala string 'frajer'?
E, pa, ovo se desilo zato što i moduli, kao i funkcije imaju scope, tj delovanje promenljivih je vezano za ono što je unutar modula (kao što promenljive u funkcijama imaju delovanje samo unutar tih funkcija). Ovo može biti konfuzno, zar ne? Probaj da u prethodnom primeru red u kome su naredbe from i import pomeriš ispod definicije promenljive __version__. Šta se dešava? Zašto?
Budući da se stvari na ovaj način dosta komplikuju, i da u ovakvim slučajevima više ne znamo šta je, i odakle došlo, gde je definisano, i sl. postaje očigledno da ovakav način rada treba da se izbegava. Najpametnije je koristiti import naredbu iako se čini da je zbog nje sam program malo duži.
No, hajde još jedan eksperiment:
>>> from baba_sera import * 
>>> __version__ 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
NameError: name '__version__' is not defined 
>>> drukanje() 
Halooo? Dobar dan, ovde baba sera . 
Da vidite kako se današnja omladina pokvareno ponaša! 
Ali ne brinite, sve sam ih čula, nanu im li njiovu... 
Pa ću sad da Vam ispričam... 
Evo šta su pričali pokvarenjaci 


Ja sam strašan frajer . 
I pošto mi se sviđa što si plavuša , 
Mogli bi smo da se upoznamo. 
Kako se zoveš? 


Zovem se Jelena. 



Nadam se da ćete učiniti nešto po tom pitanju! 
>>> 
Pokrenuo sam interaktivni prompt u direktorijumu u kojem su naše skripte, a zatim sam koristio: 
from baba_sera import * 
Što je izvršilo uvoz svih definisanih imena u modulu baba_sera, kao što je naziv funkcije drukanje(), ali što je zanimljivo, ne uvozi promenljivu __version__ , jer njeno ime počinje sa duplom donjom crtom. Šta ovo znači? Pa, zamisli da je program neka osoba koja ima nešto što želi da svi znaju, i što predstavlja njen identitet, tj ima nešto što je javno. Takođe, ta osoba ima pravo i da ima svoje neke svoje stvari koje su privatne, koje nisu namenjene svima, koje su njena (bezuspešno čuvana) tajna.
Vodeći se tom logikom, kada pišemo programe u Pythonu, i kada dodeljujemo imena različitim objektima, funkcijama i promenljivima, treba da se vodimo sledećim načelom: ukoliko funkcija / objekat / promenljiva služe samo za njegovu internu upotrebu, imena koje im dodeljujemo treba da počinju sa donjim crtama. Ukoliko su namenjeni za neku „spoljašnju“ upotrebu, onda im dajemo nazive koji počinju sa slovom. Naravno da i ovde postoje izuzeci, ali za sada zapamti ovo.
Sledeći tu logiku, vidimo i zašto nam Python nije mogao prikazati __version__ promenljivu, za njega – to je nešto što pripada modulu. Ali, budući da je funkcija drukanje() u stvari funkcija u modulu, ona je sasvim normalno mogla da „pročita“ privatnu promenljivu __version__ tog svog modula, pa ju je i – prikazala.
Mislim da je sad trenutak da ti predstavim i nešto što se naziva Zen Python-a!
Zen? Jel to neka filozofija, ako se ja dobro razumem u terminologiju?
Hehehe, sad ćeš da vidiš!
Jedan od važnih principa programiranja u Pythonu je: "Eksplicitno je bolje nego Implicitno". Ako se pitaš odakle mi ovo, pokreni interaktivni prompt i ukucaj komandu:
>>> import this 
pa ako ti nije nešto jasno, pogledaj ovu diskusiju na sajtu StackOverflow u kojoj se vodila polemika, i u kojoj su davani primeri za svaki od ovih principa.

10.3 Ime modula Indeks 10.5 Funkcija dir

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

0 Коментари