Itt vagy: Kezdőlap ‣ Ugorj fejest a Python 3-ba ‣
Nehézségi szint: ♦♢♢♢♢
❝ Ne temesd terhed a szentek némaságába. Problémád van? Nagyszerű. Örvendj, merülj el, és vizsgálódj. ❞
– Ven. Henepola Gunaratana
A megállapodás előírja, hogy a programozás alapvető építőköveivel kell untassalak, hogy lassan felépíthessünk valami hasznosat. Hagyjuk ezt ki. Ez itt egy teljes, működő Python program. Valószínűleg semmi értelme nincs számodra. Ne aggódj emiatt, hamarosan sorról sorra felboncoljuk. De előtte olvasd el, és próbálj meglátni benne valami értelmet.
SUFFIXES = {1000: ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
1024: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']}
def approximate_size(size, a_kilobyte_is_1024_bytes=True):
'''Egy fájlméret emberek által olvasható formába konvertálása.
Kulcsszó argumentumok:
size -- a fájlméret bájtban
a_kilobyte_is_1024_bytes -- ha True (alapértelmezett), akkor az 1024 többszöröseit használja
ha False, akkor az 1000 többszöröseit használja
Visszaad: karakterláncot
'''
if size < 0:
raise ValueError('a szám nem lehet negatív')
multiple = 1024 if a_kilobyte_is_1024_bytes else 1000
for suffix in SUFFIXES[multiple]:
size /= multiple
if size < multiple:
return '{0:.1f} {1}'.format(size, suffix)
raise ValueError('a szám túl nagy')
if __name__ == '__main__':
print(approximate_size(1000000000000, False))
print(approximate_size(1000000000000))
Most futtassuk ezt a programot a parancssorban. Windowson ez valahogy így néz ki:
c:\Documents and Settings\te\diveintopython3\examples> c:\python32\python.exe humansize.py 1.0 TB 931.3 GiB
Mac OS X vagy Linux alatt valahogy így fog kinézni:
te@localhost:~/diveintopython3/examples$ python3 humansize.py 1.0 TB 931.3 GiB
Mi történt? Végrehajtottad az első Python
programod. Meghívtad a Python parancsértelmezőt a parancssorból, és
átadtad neki annak a parancsfájlnak a nevét, amelyet a Pythonnal futtatni
akartál. A parancsfájl egyetlen függvényt, az
approximate_size()
függvényt hívja meg, amely egy bájtban
megadott pontos fájlméretet kap, és kiszámít egy „szép”
(de közelítő) méretet. (Ezt valószínűleg láttad már a Windows Intézőben,
vagy a Mac OS X Finderben, vagy Linuxon a Nautilusban, a Dolphinban vagy a
Thunarban. Ha egy dokumentumokat tartalmazó mappát többoszlopos listaként
jelenít meg, akkor a táblázatban a dokumentum ikonja, neve, mérete,
típusa, legutóbbi módosítás dátuma stb. jelenik meg. Ha a mappa egy 1093
bájtos TODO
nevű fájlt tartalmaz, akkor a fájlkezelő a
TODO 1093 bájt
helyett valami olyasmit fog kiírni, hogy
TODO 1 KB
. Ezt csinálja az approximate_size()
függvény is.)
Nézd meg a parancsfájl alját, itt a print(approximate_size(argumentumok))
függvény két hívását láthatod.
Ezek függvényhívások – először az
approximate_size()
függvényt hívják meg, átadva néhány
argumentumot, majd a visszatérési értéket azonnal átadják a
print()
függvénynek. A print()
függvény
beépített, soha nem fogod az explicit deklarációját látni. Egyszerűen
használhatod, bármikor, bárhol. (Rengeteg beépített függvény van, és
annál is több van modulokba szervezve. Türelem, prücsök.)
Miért adja a parancssorból futtatott parancsfájl mindig ugyanazt a
kimenetet? Azt is megnézzük. Először nézzük azonban az
approximate_size()
függvényt.
⁂
A Python a legtöbb nyelvhez hasonlóan rendelkezik függvényekkel, de
nincsenek önálló fejlécfájlok, mint a C++-ban vagy
interfész
/megvalósítás
szakaszok, mint a
Pascalban. Ha egy függvényre van szükséged, egyszerűen csak deklaráld, így:
def approximate_size(size, a_kilobyte_is_1024_bytes=True):
A def
kulcsszó elindítja a függvénydeklarációt, amelyet
a függvény neve és zárójelek közt a paraméterek követnek. Több
paraméter vesszőkkel választható el.
Vedd észre, hogy a függvény nem definiál visszatérési adattípust. A
Python függvények nem adják meg a visszatérési értékük adattípusát, sőt
azt sem, hogy egyáltalán visszaadnak-e értéket. (Valójában minden Python
függvény visszaad egy értéket; ha a függvény végrehajt egy
return
utasítást, akkor annak értékét adja vissza, ellenkező
esetben a None
értéket, a Python nullértékét.
☞Egyes nyelvekben (az értéket visszaadó) függvények a
function
, míg a szubrutinok (amelyek nem adnak vissza értéket) asub
kulcsszóval kezdődnek. Pythonban nincsenek szubrutinok. Minden függvény, minden funkció visszaad egy értéket (még ha az aNone
is), és minden függvény adef
kulcsszóval kezdődik.
Az approximate_size()
függvény két – a
size és
a_kilobyte_is_1024_bytes – paramétert vár, de
egyik paraméter sem ad meg adattípust. Pythonban a változók soha
nem kifejezetten típusosak. A Python meghatározza a változó típusát, és
azt saját maga tartja nyilván.
☞Java és más statikusan típusos nyelveknél meg kell adnod a függvény visszatérési értékének és minden egyes függvényparaméter adattípusát. Pythonban soha nem kell kifejezetten megadni semminek az adattípusát. A hozzárendelt érték alapján a Python saját maga tartja nyilván az adattípust.
A Python lehetővé teszi, hogy a függvényparaméterek alapértelmezett értékkel rendelkezzenek, ha a függvény argumentum nélkül kerül meghívásra, akkor az argumentum az alapértelmezett értéket kapja. Ezen kívül az argumentumok tetszőleges sorrendben is megadhatók nevesített argumentumok használatával.
Vessünk egy újabb pillantást az
approximate_size()
függvény deklarációjára:
def approximate_size(size, a_kilobyte_is_1024_bytes=True):
A második paraméter, az a_kilobyte_is_1024_bytes megad egy
alapértelmezett értéket, ez a True
. Ez azt jelenti, hogy
a paraméter elhagyható; a függvény meghívható nélküle is, és a
Python úgy fog viselkedni, mintha a második paramétere a True
lett volna.
Most nézd meg a parancsfájl alját:
if __name__ == '__main__':
print(approximate_size(1000000000000, False)) ①
print(approximate_size(1000000000000)) ②
approximate_size()
függvényt két argumentummal
hívja meg. Az approximate_size()
függvényen belül az
a_kilobyte_is_1024_bytes értéke False
lesz, mivel
második argumentumként a False
értéket adjuk át.
approximate_size()
függvényt csak egy argumentummal
hívja meg. De ez nem gond, mivel a második argumentum elhagyható! Mivel a
hívó nem adja meg, a második argumentum az alapértelmezett
True
értéket kapja meg, ahogyan az a függvény deklarációjában
meg van határozva.
A függvénynek név szerint is átadhatsz értékeket.
>>> from humansize import approximate_size >>> approximate_size(4000, a_kilobyte_is_1024_bytes=False) ① '4.0 KB' >>> approximate_size(size=4000, a_kilobyte_is_1024_bytes=False) ② '4.0 KB' >>> approximate_size(a_kilobyte_is_1024_bytes=False, size=4000) ③ '4.0 KB' >>> approximate_size(a_kilobyte_is_1024_bytes=False, 4000) ④ File "<stdin>", line 1 SyntaxError: non-keyword arg after keyword arg >>> approximate_size(size=4000, False) ⑤ File "<stdin>", line 1 SyntaxError: non-keyword arg after keyword arg
approximate_size()
függvényt a 4000
első argumentummal (size) hívja meg, és a False
értékkel az a_kilobyte_is_1024_bytes paraméterhez. (Ez most a
második argumentum, de nem számít, ahogy mindjárt látni fogod.)
approximate_size()
függvényt a 4000
argumentummal hívja meg a size paraméterhez, és a
False
értékkel az a_kilobyte_is_1024_bytes
paraméterhez.
(Ezek a nevesített argumentumok ugyanabban a sorrendben vannak felsorolva,
mint a függvénydeklarációban, de ez sem számít.)
approximate_size()
függvényt a
False
értékkel hívja meg az
a_kilobyte_is_1024_bytes nevű paraméterhez, és a
4000
értékkel a size nevű paraméterhez. (Látod? Megmondtam, hogy a sorrend nem számít.)
4000
értéket a size
nevű paraméternek
adtad át, „nyilvánvaló”, hogy a False
értéket az
a_kilobyte_is_1024_bytes paraméternek szántad. De a Python
nem így működik. Amint van egy nevesített argumentumod, attól jobbra
minden argumentumnak nevesítettnek kell lennie.
⁂
Nem foglak hosszú hegyibeszéddel untatni a kódod dokumentálásának fontosságáról. Azt tartsd észben, hogy a kódot egyszer írják, de sokszor olvassák, és a kódod legfontosabb közönsége te vagy, hat hónappal a megírása után (azaz amikor már mindent elfelejtettél, de valamit ki kell javítanod). A Python egyszerűvé teszi az olvasható kód írását, használd ezt ki. Hat hónap múlva meg fogod köszönni.
A Python függvényeket egy dokumentációs karakterlánc
(röviden és angolul docstring
) megadásával dokumentálhatod.
Ebben a programban az approximate_size()
függvénynek van
docstring
-je:
def approximate_size(size, a_kilobyte_is_1024_bytes=True):
'''Egy fájlméret emberek által olvasható formába konvertálása.
Kulcsszó argumentumok:
size -- a fájlméret bájtban
a_kilobyte_is_1024_bytes -- ha True (alapértelmezett), akkor az 1024 többszöröseit használja
ha False, akkor az 1000 többszöröseit használja
Visszaad: karakterláncot
'''
A három idézőjel többsoros karakterláncot jelez. A kezdő és záró
idézőjelek között minden egyetlen karakterlánc része, beleértve a
sortöréseket, a kezdő üres helyeket és más idézőjel karaktereket. Ezeket
bárhol használhatod, de leggyakrabban a docstring
megadásakor
láthatod őket.
☞A három idézőjel segítségével egyszerűen adhatsz meg olyan karakterláncot, amely egyszeres és dupla idézőjelet is tartalmaz, a Perl 5
qq/.../
kulcsszavához hasonlóan.
A három idézőjelen belül minden a függvény docstring
-je,
amely a függvény működését dokumentálja. A docstring
-et, ha
van, a függvényben elsőként kell megadni (azaz a függvénydeklaráció utáni
sorban). Technikailag nem kötelező a függvényhez docstring
-et
megadnod, de jobban jársz a megadásával. Tudom, hogy ezt minden
programozás órán elmondták, de a Python további motivációt ad: a
docstring
futás közben a függvény attribútumaként is elérhető.
☞Sok Python IDE a
docstring
-et használja helyzetérzékeny dokumentáció biztosítására, így amikor beírod egy függvény nevét, a hozzá tartozódocstring
megjelenik a buboréksúgóban. Ez hihetetlenül hasznos tud lenni, de csak annyira, amennyire az általad írtdocstring
-ek.
⁂
import
keresési útvonalaMielőtt továbbmegyünk, röviden szeretném megemlíteni a függvénytárak
keresési útvonalát. A Python több helyen is keresi az importálni kívánt
modulokat. Pontosabban, a sys.path
által meghatározott
könyvtárakban. Ez csak egy lista, és egyszerűen megjelenítheted vagy
módosíthatod a szabványos listakezelési módszerekkel. (A listákról a Natív adattípusok fejezetben tudhatsz
meg többet.)
>>> import sys ① >>> sys.path ② ['', '/usr/lib/python32.zip', '/usr/lib/python3.2', '/usr/lib/python3.2/plat-linux2@EXTRAMACHDEPPATH@', '/usr/lib/python3.2/lib-dynload', '/usr/lib/python3.2/dist-packages', '/usr/local/lib/python3.2/dist-packages'] >>> sys ③ <module 'sys' (built-in)> >>> sys.path.insert(0, '/home/mark/diveintopython3/examples') ④ >>> sys.path ⑤ ['/home/mark/diveintopython3/examples', '', '/usr/lib/python32.zip', '/usr/lib/python3.2', '/usr/lib/python3.2/plat-linux2@EXTRAMACHDEPPATH@', '/usr/lib/python3.2/lib-dynload', '/usr/lib/python3.2/dist-packages', '/usr/local/lib/python3.2/dist-packages']
sys
modul importálása minden függvényét és attribútumát elérhetővé teszi.
sys.path
könyvtárnevek listája, amelyek az aktuális
keresési útvonalat alkotják. (A tiéd másképp fog kinézni, függően az
operációs rendszeredtől, a Python verziójától, és annak eredeti
telepítési helyétől.) A Python ezekben a könyvtárakban fogja keresni
(ebben a sorrendben) azt a .py
fájlt, amelynek neve
megegyezik azzal, amit importálni próbálsz.
.py
fájlokként tárolva. Egyes modulok
beépítettek; valójában bele vannak drótozva magába a Pythonba. A
beépített modulok úgy viselkednek, mint a normális modulok, de a Python
forráskódjuk nem érhető el, mivel nem Pythonban vannak írva! (Mint
maga a Python, ezek a beépített modulok is C-ben íródtak.)
sys.path
-hoz adásával, ezután a Python abban a
könyvtárban is keresni fogja az importált modulokat. Ennek hatása addig
tart, amíg a Python értelmező fut.
sys.path.insert(0, új_útvonal)
használatával
beszúrtál egy új könyvtárat a sys.path
lista első elemeként,
emiatt a Python keresési útvonalának elejére. Majdnem mindig ezt
szeretnéd. Elnevezési ütközések esetén (ha például a Python egy adott
függvénytár 2-es verzióját szállítja, de a 3-as verziót szeretnéd
használni), akkor ez biztosítja, hogy a moduljaidat a Python a beépített
modulok előtt találja meg és használja.
⁂
Ha elsiklottál volna fölötte, akkor az előbb azt mondtam, hogy a Python függvényeknek attribútumaik vannak, és azok az attribútumok futás közben elérhetők. A függvények, mint minden más is Pythonban, objektumok.
Indítsd el az interaktív Python parancsértelmezőt, és próbáld ki ezt:
>>> import humansize ① >>> print(humansize.approximate_size(4096, True)) ② 4.0 KiB >>> print(humansize.approximate_size.__doc__) ③ Egy fájlméret emberek által olvasható formába konvertálása. Kulcsszó argumentumok: size -- a fájlméret bájtban a_kilobyte_is_1024_bytes -- ha True (alapértelmezett), akkor az 1024 többszöröseit használja ha False, akkor az 1000 többszöröseit használja Visszaad: karakterláncot
humansize
programot modulként
importálja – ez egy olyan kóddarab, amelyet interaktívan vagy
egy nagyobb Python programból is használhatsz. Egy modul importálása után
bármely nyilvános függvényére, osztályára vagy attribútumára
hivatkozhatsz. A modulok ezzel elérhetik más modulok funkcionalitását, és
ezt a Python interaktív parancsértelmezőjéből te is megteheted. Ez egy
fontos fogalom, és rengetegszer fogod látni ebben a könyvben.
approximate_size
függvényre; hanem csak a
humansize.approximate_size
függvényre. Ha használtál
osztályokat Javaban, akkor ez nagyjából ismerős kell legyen.
__doc__
-ot kéred le.
☞Az
import
Pythonban olyan, mint arequire
Perlben. Azimport
használatával beágyazott Python modult függvényeitmodul.függvény
formában érheted el; arequire
használatával beágyazott Perl modul függvényeit amodul::függvény
formában érheted el.
Pythonban minden objektum, és mindennek lehetnek attribútumai és
metódusai. Minden függvénynek van egy beépített __doc__
nevű
attribútuma, amely a függvény forráskódjában definiált
docstring értékét adja vissza. A sys
modul egy
objektum, amely rendelkezik (többek között) egy path nevű
attribútummal. És így tovább.
Ez azonban még mindig nem válaszolja meg az alapkérdést: mi az az objektum? A különböző programozási nyelvek különbözőképpen definiálják az „objektum” fogalmát. Egyesekben ez azt jelenti, hogy minden objektumnak rendelkeznie kell attribútumokkal és metódusokkal, másokban azt jelenti, hogy minden objektumból származtatható osztály. Pythonban a definíció lazább. Egyes objektumoknak nincsenek sem attribútumai, sem metódusai, de lehetne nekik. Nem minden objektumból származtathatók osztályok. De minden objektum abban az értelemben, hogy változóhoz rendelhetők, vagy átadhatók egy függvény argumentumaként.
Más programozási nyelvek kapcsán hallhattad az „első osztályú objektum” kifejezést. Pythonban a függvények első osztályú objektumok. Egy függvény átadható argumentumként egy másik függvénynek. A modulok első osztályú objektumok. Egy egész modult átadhatsz argumentumként egy függvénynek. Az osztályok első osztályú objektumok, és az osztályok egyes példányai is első osztályú objektumok.
Ez fontos, ezért megismétlem, ha az első néhány alkalommal lemaradtál róla: Pythonban minden objektum. A karakterláncok objektumok. A listák objektumok. A függvények objektumok. Az osztályok objektumok. Az osztálypéldányok objektumok. Még a modulok is objektumok.
⁂
A Python függvények nem rendelkeznek explicit kezdettel
vagy véggel
, és nem jelöli kapcsos zárójel a függvények
kezdetét és végét. Az egyetlen határoló a kettőspont (:
) és
maga a kódbehúzás.
def approximate_size(size, a_kilobyte_is_1024_bytes=True): ①
if size < 0: ②
raise ValueError('a szám nem lehet negatív') ③
④
multiple = 1024 if a_kilobyte_is_1024_bytes else 1000
for suffix in SUFFIXES[multiple]: ⑤
size /= multiple
if size < multiple:
return '{0:.1f} {1}'.format(size, suffix)
raise ValueError('a szám túl nagy')
if
utasításokat, for
ciklusokat, while
ciklusokat és hasonlókat értek. A
behúzás elkezdi a blokkot, és a behúzás vége befejezi. Nincsenek explicit
kapcsos zárójelek, szögletes zárójelek vagy kulcsszavak. Ez azt jelenti,
hogy az üres helynek jelentősége van, és konzisztensnek kell lennie. Ebben
a példában a függvény kódját négy szóköz húzza be. Nem kell mindig négy
szóköznek lennie, csak konzisztensnek. Az első sor, amely nincs behúzva,
jelzi a függvény végét.
if
utasítást egy kódblokk követi. Ha az
if
kifejezés értéke igaz, akkor a behúzott blokk kerül
végrehajtásra, ellenkező esetben az else
blokk (ha van). Vedd
észre a zárójelek hiányát a kifejezés körül.
if
kódblokkon belül van. Ez a
raise
utasítás egy (ValueError
típusú) kivételt fog
dobni, de csak ha a size < 0
.
for
ciklus is a kódblokk kezdetét jelzi. A kódblokkok
több sort is tartalmazhatnak, amíg ugyanannyival vannak behúzva. Ez a
for
ciklus három sort tartalmaz. A többsoros
kódblokkoknak nincs speciális szintaxisuk. Csak húzd be őket, és haladj.
Némi kezdeti tiltakozás és rosszindulatú Fortranhoz hasonlítgatás után meg fogsz ezzel békülni, és elkezded látni az előnyeit. Az egyik nagy előnye, hogy minden Python program hasonlóan néz ki, mert a behúzás a nyelv követelménye, és nem stílus kérdése. Ez egyszerűbbé teszi mások Python kódjának olvasását és megértését.
☞A Python sortöréseket használ az utasítások elválasztására, és kettőspontot és behúzást a kódblokkok elválasztására. A C++ és Java pontosvesszőket használnak az utasítások elválasztására, és kapcsos zárójeleket a kódblokkok elválasztására.
⁂
A Python tele van kivételekkel. Gyakorlatilag a szabványos függvénytár minden modulja használja ezeket, és maga a Python is rengeteg különböző helyzetben dob kivételeket. A könyvben újra és újra találkozni fogsz velük.
Mi az a kivétel? Általában egy hiba, azt jelzi, hogy valami nem sikerült. (Nem minden kivétel hiba, de egyelőre ezzel ne foglalkozz.) Egyes programozási nyelvek a visszatérési kódok használatát bátorítják, amelyeket ellenőrizhetsz. A Python a kivételek használatát bátorítja, amelyeket kezelhetsz.
Amikor hiba történik a Python parancsértelmezőben, akkor kiír néhány részletet a kivételről és a bekövetkezésének körülményeiről, és ennyi. Ezt kezeletlen kivételnek hívjuk. A kivétel dobásakor nem volt jelen kód az észrevételéhez és kezeléséhez, így az feljutott a Python parancsértelmező felső szintjére, amely kiköp némi hibakeresési információt, és ennyivel megoldottnak tekinti a problémát. A parancsértelmezőben ez nem gond, de ha egy tényleges Python program futása közben történt volna, akkor - hacsak valami nem kezeli a kivételt - az egész program összeomlott volna. Lehet, hogy ezt akarod, lehet, hogy nem.
☞A Javaval ellentétben a Python függvények nem deklarálják, hogy milyen kivételeket dobhatnak. Rád van bízva, hogy meghatározd, milyen esetleg bekövetkező kivételeket kell elkapnod.
Egy kivétel azonban nem okozza szükségszerűen a teljes program
összeomlását. A kivételek kezelhetők. Néha egy kivétel csak a
kódod hibáját jelzi (például nem létező változót próbálsz elérni), de néha
a kivétel egy várható dolog. Amikor megnyitsz egy fájlt, akkor
előfordulhat, hogy az nem létezik. Amikor importálsz egy modult, akkor
előfordulhat, hogy az nincs telepítve. Amikor egy adatbázishoz
csatlakozol, akkor előfordulhat, hogy az nem érhető el, vagy nincsenek
megadva az eléréséhez szükséges hitelesítési adatok. Ha tudod, hogy egy
kódsor kivételt dobhat, akkor azt a kivételt kezelned kell egy
try...except
blokkal.
☞A Python a
try...except
blokkokat használja a kivételek kezelésére, és araise
utasítást az előállításukra. A Java és a C++ atry...catch
blokkokat használják a kivételek kezelésére, és athrow
utasítást az előállításukra.
Az approximate_size()
függvény két különböző esetben dob
kivételt: ha a megadott size értéke nagyobb, mint aminek a
kezelésére a függvény tervezve van, vagy ha az kisebb, mint nulla.
if size < 0:
raise ValueError('a szám nem lehet negatív'')
A kivétel dobásának szintaxisa elég egyszerű. Add meg a
raise
utasítást, majd a kivétel nevét, és egy elhagyható,
emberek által olvasható karakterláncot hibakeresési célokra. A szintaxis
hasonlít egy függvény hívásához. (A valóságban a kivételek osztályokként
vannak megvalósítva, és ez a raise
utasítás példányosítja a
ValueError
osztályt, és átadja neki az 'a szám nem
lehet negatív''
karakterláncot az inicializálási metódusában. De ezzel most előre szaladtam!)
☞A kivételt nem kötelező abban a függvényben kezelned, amely dobja. Ha egy függvény nem kezeli, akkor a kivétel átadásra kerül a hívó függvénynek, ezután annak a hívó függvényének és így tovább a „hívási láncon.” Ha a kivétel soha nem kerül kezelésre, akkor a program összeomlik, és a Python kiír egy „visszakövetést” a szabványos hibakimenetre, és ezzel vége. Ismétlem, lehet, hogy ezt akarod, attól függ, hogy mit csinál a programod.
A Python egyik beépített kivétele az ImportError
, amelyet
akkor dob, amikor megpróbálsz importálni egy modult, de az nem sikerül.
Ez rengeteg okból bekövetkezhet, de a legegyszerűbb, hogy a modul nem
létezik az import keresési útvonalán. Ezt
elhagyható szolgáltatások felvételére használhatod a programodba. Például
a chardet
függvénytár a karakterkódolás automatikus felismerését nyújtja. Lehet,
hogy a programod használni akarja ezt a könyvtárat, ha létezik,
de akkor is elegánsan folytatódik, ha a felhasználó nem telepítette. Ezt
egy try..except
blokkal oldhatod meg.
try:
import chardet
except ImportError:
chardet = None
Később a chardet
modul jelenlétét egy egyszerű
if
utasítással ellenőrizheted:
if chardet:
# csinál valamit
else:
# így is folytatódik
Az ImportError
kivétel másik gyakori használati módja,
amikor két modul valósít meg egy közös API-t, de az egyik
valamiért jobb, mint a másik. (Például gyorsabb vagy kevesebb memóriát
használ.) Megpróbálhatod importálni az egyik modult, de használhatsz egy
másik modult, ha az első importálás meghiúsul. Az XML
fejezet például két modulról beszél, amelyek megvalósítanak egy közös
API-t, az ElementTree
nevű API-t.
Az első, az lxml
egy külső modul, amelyet saját magadnak kell
letöltened és telepítened. A második, az
xml.etree.ElementTree
lassabb, de része a Python 3 szabványos
függvénytárának.
try:
from lxml import etree
except ImportError:
import xml.etree.ElementTree as etree
Ennek a try..except
blokknak a végére importáltál
egy modult, amit etree-nek nevezel. Mivel mindkét
modul egy közös API-t valósít meg, a kódod többi részének nem
kell folyton ellenőriznie, hogy melyik modul lett importálva. Mivel a
ténylegesen importált modul neve mindig etree, a kódot
nem kell teleszemetelni if
utasításokkal, hogy más-más nevű
modulokat hívjanak.
⁂
Vessünk egy újabb pillantást az approximate_size()
függvény ezen sorára:
multiple = 1024 if a_kilobyte_is_1024_bytes else 1000
A multiple változót sehol nem deklarálod, csak hozzárendelsz
egy értéket. Ez rendben van, mert a Python lehetővé teszi. Amit a Python
nem fog lehetővé tenni, az egy olyan változóra hivatkozás,
amelyhez soha nem rendeltél értéket. Ha megpróbálod, akkor a Python egy
NameError
kivételt fog dobni.
>>> x Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'x' is not defined >>> x = 1 >>> x 1
Egy napon ezt meg fogod köszönni a Pythonnak.
⁂
A Pythonban minden név megkülönbözteti a kis- és nagybetűket: változónevek, függvénynevek, osztálynevek, modulnevek, kivételnevek. Ha le tudod kérdezni, be tudod állítani, meg tudod hívni, létre tudod hozni, importálni vagy dobni tudod, akkor megkülönbözteti a kis- és nagybetűket.
>>> egy_változó = 1 >>> egy_változó 1 >>> EGY_VÁLTOZÓ Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'EGY_VÁLTOZÓ' is not defined >>> Egy_Változó Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'Egy_Változó' is not defined >>> egy_válTozó Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'egy_válTozó' is not defined
És így tovább.
⁂
A Python modulok objektumok, és számos hasznos attribútummal
rendelkeznek. Ezt a moduljaid egyszerű tesztelésére használhatod azok
írása közben. Csak vegyél fel egy speciális blokkot, amely lefut a Python
fájl parancssorban való futtatásakor. Vegyük a humansize.py
utolsó néhány sorát:
if __name__ == '__main__':
print(approximate_size(1000000000000, False))
print(approximate_size(1000000000000))
☞A C-hez hasonlóan a Python is az
==
operátort használja az összehasonlításra, és az=
operátort az értékadásra. A C-vel szemben a Python nem támogatja a beágyazott értékadást, így nem tudod véletlenül hozzárendelni azt az értéket, amelyet össze akartál hasonlítani.
Akkor mi teszi ezt az if
utasítást olyan különlegessé?
Nos, a modulok objektumok, és minden modulnak van egy beépített
__name__
attribútuma. A modul __name__
attribútumának értéke attól függ, hogyan használod a modult. Ha
import
utasítással importálod a modult, akkor a
__name__
értéke a modul fájlneve lesz, könyvtárelérési út
vagy fájlkiterjesztés nélkül.
>>> import humansize >>> humansize.__name__ 'humansize'
A modult azonban közvetlenül is futtathatod önálló programként, ebben
az esetben a __name__
egy speciális alapértelmezett
értéket kap, ez a __main__
. A Python kiértékeli ezt az
if
utasítást, igaz kifejezést talál, és végrehajtja az
if
kódblokkját. Ebben az esetben két értéket ír ki.
c:\home\diveintopython3> c:\python32\python.exe humansize.py 1.0 TB 931.3 GiB
És ez volt az első Python programod!
⁂
docstring
-et a nagyszerű docstring
-től.
© 2001–11 Mark Pilgrim