Informatika2-2012/Eloadas09
Tartalomjegyzék |
függvények definiálása és használata
Amikor függvényeket definiálunk, akkor igazán nem fut le semmilyen létrehozott kod, csak egy ellenőrzés, amivel kizárja az interpreter a szintaktikai hibákat (olyan hiba ami a kod szövegéből ered).
A függvényben megírt kód csak a függvény hívásakor fut le és a változói akkor lesznek kiértékelve.
def fvdef(): pass # a pass egy olyan parancs ami nem csinal semmit return x**2-1
Itt meg nem futott le semmi csak a fuggvény hívásakor.
fvdef()
Maga a függvényben definiált kód csak a meghívásakor fut le.
Meghívni a függvényt a függvény nevével lehet, úgy hogy utána a zárójelben megadjuk a paraméterként szánt értékeket. (Ha nem kell megadni paramétert akkor csak üres zárójelet használunk... "()")
alapértelmezett paraméter érték
Ha csak simán definiálunk egy függvényt amiket paraméterekkel lehet csak használni, akkor azok a paraméterek kötelezöek
def a_d_test(fv, vert): return fv * vert a_d_test(5) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: a_d_test() takes exactly 2 arguments (1 given)
Ezért lehetséges alapértelmezett értékeket beállítani a definiálás során, ez az érték egyszer értékelődik ki és utána mindig az lesz az alapértelmezett.
def a_d_test(fv, vert = 1): return fv * vert a_d_test(5) 5
Fontos hogy azok a paraméterek amiket alapértelmezett értékkel akarunk ellátni a paraméterezésben hátulról kell beilleszteni.
SyntaxError: non-default argument follows default argument
kulcsszavas paraméter érték
Lehetséges a paraméterek neveivel is átadni a kívánt elemeket:
a_d_test(vert=2, fv=2)
Itt is fontos, hogy ha valamit kulcsszóval akarunk átadni, akkor azt a függvény hívás paraméterlistájának végétől kell feltölteni.
tetszőleges számú paraméter kezelése
Lehetőség van tetszőleges számú paramétert kezelni a *<nev> paraméter elkérésével
def as_many(*args): for i in args: print i, as_many('trali', 'fari') trali fari
tetszőleges nevesített paraméterek
def as_many_as(**args): for k,v in args.iteritems(): print k, "erteke: ", v as_many_as(elso='trali', masodik='fari') elso erteke: trali masodik erteke: fari
Ahogy láthatjuk itt nevet adhatunk az értéknek és nem csak a pozíciója határozza meg hogy mihez is lehet kötni az elemet. Fontos hogy mivel nem számíthatunk hogy megkapjuk-e azt a paramétert a függvény hívásakor ezért mindig ellenőrizzük annak meglétét.
Változók érvényességi köre
A nevek egy változóra hivatkoznak. Egy blokk olyan programrész, ami egy egységként hajtódik végre. A mi esetünkben egy függvény törzse blokk (de egy parancs is blokként értelmezett).
Egy blokk futtatása úgynevezett "futtatási keretben" történik (administrációs és futtatási okokból).
A scope a láthatóságát jelenti az adot változónak.
- ha változót deklarálunk egy blokkon belül akkor annak láthatósága arra a blokra korlátozódik
- ha a blokkon belül újabb blokkot hozunk létre, akkor ott is értelmezett lesz a változó, kivéve ha a belső blokkon belül azt nem definiáljuk felül, azaz nem adunk értéket neki
- továbbá ha a külső blokkbeli változót szeretnénk használni, majd annak értéket adni a belső blokkban, az hibát fog okozni, mert ugyan bárhol deklarálhatunk változót, de blokkon belül a deklaráció előtt nem lehet használni azt a változót.
def fv(): return a a=7 fv()
Látható, hogy a külső blokkban deklarált "a" változó látható a függvényen belül is.
a=7 def sz2(): a=2 return a print a print sz2() print a
Latható, hogy ha a belső blokkon belül deklarálunk már létező névvel új változót, akkor az csak a belső blokkon belül lesz értelmezett.
a=7 def sz3(): b=a a=6 return b Traceback (click to the left of this block for traceback) ... UnboundLocalError: local variable 'a' referenced before assignment
Látszik, hogy "a" ugyan létezik, de mivel a belső blokkon belül újra deklaráljuk, igy a deklaráció előtt nem használhatjuk azt.
A hiba egyszerű de nem szép megoldására a python a global kulcsszót adja a kezünkbe.
a=7 def sz3(): global a b=a a=6 return b
Programtervezési irányelveket követve az előző hibát más eszközökkel kell megoldani.
Program struktúra
A python lehetőséget ad bonyolult program szétdarabolására hogy az átláthatóbb legyen a fejlesztők számára A csomagok és a modulok kialakításával érhetjük el a darabolást.
csomag
Kiszervezhető és akár önmagukban is futtatható nagyobb független kódrészletekre használatos. Egy adott területhez tartozó feladatokat látja el. Általában több modul és alcsomagokat tartalmaz.
Pl: numpy - "NumPy is the fundamental package for scientific computing with Python."
Mitől lesz valami csomag? Csomaggá az a könyvtár változhat ami tartalmazza a __init__.py fájlt. Ez a fájl jelzi az fordító számára, hogy egy csomagról van szó. A __init__.py üresen is elég, de vannak extra változók amiket lehet használni a csomag könnyebb használata érdekében (__all__, __path__, ...)
modul
Kisebb egybefüggő programrészek egysége. Maga a python programot tartalmazó file egy modult képez.
A modul neve a file nevével egyezik amiben van a kód. Így pl.: a protak.py programfájlban lévő modulra a protak névvel tudunk hivatkozni. A modul nevét a programon belül a __name__ változóval érjük el. Fontos, hogy ha a modult mint program indítjuk akkor a __name__ értéke __main__ lesz! Ezt fel lehet használni pl.:
tortin.py fájl tartalma:
def mainp(): print "This is the main" def elp(): print 'This is not the main' if __name__ == '__main__': mainp() else: elp()
Majd hivjuk meg konzolbol a
python tortin.py
illetve interpreterből...
import tortin
(A modul elnevezést szokás használni még azokra a csomagokra is amiket különálló általános problémákat lehet kezelni pl. numpy és azokra amik kiterjesztési csomagok azaz más nyelvhez (pl.: C) való kapcsolódást valósít meg.)
csomagok és modulok felhasználása (import)
A programrészeket felhasználhatjuk a programon belül akárhol, ha azt jelezzük a fordítónak.
A python-on belül ezt az import vagy a from és az import kulcsszavakkal tehetjük meg a következő módon.
import sys from sys import stdin from sys import maxint as mi from mymodule import *
- az import sys paranccsal az összes sys modul alatt elérhető függvényhez és változóhoz hozzáférünk. pl.: sys.maxint vagy sys.ps1
- az from sys import stdin paranccsal a programon használhatjuk a sys modulban definiált stdin változót a saját nevén, azaz a fájlon belül elérhető a stdin változó.
- a from sys import maxint as mi nagyon hasonló az előzőhöz csak itt meg megadtuk azt is hogy a mi modulunkban mi a maxint változót a mi néven akarjuk elérni.
- végül a from mymodule import * sorral azt adtuk meg, hogy mymodule minden eleme (kivéve a "_" karakterrel kezdődőek) elérhetőek legyenek. A * használata csomag import esetén kerülendő, modul esetén is megfelelő figyelemmel!
relatív import útvonalak
Bonyolultabb csomagokban ahol több alcsomag és sok-sok modul található az egymáshoz való hivatkozásokhoz használhatunk relatív útvonalakat.
from . import torti from .. import kerek from ..vaz import orr
modul és csomag nevek feloldása
Az fordító először a
- beépített modulok között keres, ha ott nem találja, akkor
- sys.path - ban lévő útvonalakat próbálja végig ami a következőképpen épül fel:
- az indítás könyvtárába
- PYTHONPATH
elérhető elemek
Az elérhető elemeket egy adott modulon belül a dir() függvénnyel listázhatjuk ki