Írunk egy Person osztályt. Minden embernek lesz neve és titulusa, a __repr__
függvénnyel pedig megszólítjuk. A Knight osztály a Person leszármazottja. Minden lovag egyben ember is, de a megszólításuk egyedi. Leszármaztatni akkor tudunk, ha az ősosztályunk is az object leszármazottja. A leszármazott örökli az ősosztály összes tagváltozóját és metódusát.
class Person(object):
def __init__(self, name, title):
self.name = name
self.title = title
def __repr__(self):
return self.title + " " + self.name
class Knight(Person):
def __init__(self, name):
super(Knight, self).__init__(name, 'Sir')
varga = Person('Varga', 'Mr')
launcelot = Knight('Launcelot')
print varga
print launcelot
A leszármazott osztályban definiálhatunk új tagváltozókat is. Például legyen minden lovagnak egy epitheton ornansa!
class Person(object):
def __init__(self, name, title):
self.name = name
self.title = title
def __repr__(self):
return self.title + " " + self.name
class Knight(Person):
def __init__(self, name, eo):
super(Knight, self).__init__(name, 'Sir')
self.eo = eo
launcelot = Knight('Launcelot', 'the brave')
launcelot
Minden lovag megérdemli, hogy a neve mellé az állandó jezőjét is hozzáfűzzük. Ehhez átdefiniáljuk a __repr__
metódust. Azonos nevű metódusok esetén mindig a leszármazottban definiált élvez elsőbbséget és hívódik meg.
class Person(object):
def __init__(self, name, title):
self.name = name
self.title = title
def __repr__(self):
return self.title + " " + self.name
class Knight(Person):
def __init__(self, name, eo):
super(Knight, self).__init__(name, 'Sir')
self.eo = eo
def __repr__(self):
return self.title + " " + self.name + ", " + self.eo
launcelot = Knight('Launcelot', 'the brave')
robin = Knight('Robin', 'the Not-quite-so-brave-as-Sir-Launcelot')
print launcelot
print robin
Van mód arra is, hogy bizonyos változókat osztályszinten definiáljunk. Ilyen például a lovagok "Sir" megszólítása. Az osztályszinten definiált title azonban egybeesik a Person title változójával így a lovagok esetében a self.title
erre a változóra mutat. Ahhoz, hogy az osztályszintű változót elérjük, a Knight.title
-ra kell hivatkozni. A searching_for
azonban már úgy viselkedik, ahogyan szeretnénk, ez osztályváltozó.
class Person(object):
def __init__(self, name, title=""):
self.name = name
self.title = title
def __repr__(self):
return self.title + " " + self.name
class Knight(Person):
title = 'Sir'
searching_for = 'The Holy Grail'
def __init__(self, name, eo):
super(Knight, self).__init__(name)
self.eo = eo
def __repr__(self):
return Knight.title + " " + self.name + ", " + self.eo
launcelot = Knight('Launcelot', 'the brave')
robin = Knight('Robin', 'the Not-quite-so-brave-as-Sir-Launcelot')
print launcelot
print robin
print launcelot.searching_for
print robin.searching_for
print launcelot.title, "-", Knight.title
print launcelot.searching_for, "-", Knight.searching_for
Megjegyezzük, hogy az öröklési lánc tetszőlegesen hosszú lehet, illetve lehet egyszerre több osztálytól örökölni.
Láttuk, hogy a for i in L
nem csak akkor működik, ha L
lista. A for
meghívja az iter()
függvényt, mely egy iterálható objektumot ad vissza, melyre definiálva van egy next()
függvény, amely minden meghívására visszaadja az objektum egy elemét. Ha a next()
nem talál több elemet, egy StopIteration
kivételt dob.
r = range(3)
it = iter(r)
it.next()
print it.next()
print it.next()
it.next()
Tetszőleges, általunk definiált osztályhoz is adható iterátor tulajdonság. Először is szükség van egy __iter__
függvényre, ami egy olyan objektummal tér vissza, ami iterálható. Az iterálható objekcumok (list, set, tuple
) definiálnak egy next()
metódust, ami sorban visszaadja az elemeket.
class Person(object):
def __init__(self, name, title=""):
self.name = name
self.title = title
def __repr__(self):
return self.title + " " + self.name
class Knight(Person):
title = 'Sir'
searching_for = 'The Holy Grail'
def __init__(self, name, eo):
super(Knight, self).__init__(name)
self.eo = eo
def __repr__(self):
return Knight.title + " " + self.name + ", " + self.eo
class Group(object):
def __init__(self, name, persons):
self.persons = persons
self.name = name
self.index = -1
def __iter__(self):
return self
def next(self):
if self.index == len(self.persons) - 1:
self.index = -1
raise StopIteration # dobunk egy kivetelt
self.index += 1
return self.persons[self.index]
kotrt = Group('Knights of The Round Table',
[Knight('Launcelot', 'the brave'),
Knight('Galahad', 'the pure'),
Knight('Bedevere', 'the wise'),
Knight('Robin', 'the Not-quite-so-brave-as-Sir-Launcelot')])
for knight in kotrt:
print knight
Vigyázzunk, hogy az indexet vissza kell állítani, különben csak egyszer tudunk iterálni! Persze mindezt megoldhattuk volna egyszerűbben.
class Person(object):
def __init__(self, name, title=""):
self.name = name
self.title = title
def __repr__(self):
return self.title + " " + self.name
class Knight(Person):
title = 'Sir'
searching_for = 'The Holy Grail'
def __init__(self, name, eo):
super(Knight, self).__init__(name)
self.eo = eo
def __repr__(self):
return Knight.title + " " + self.name + ", " + self.eo
class Group:
def __init__(self, name, persons):
self.persons = persons
self.name = name
def __iter__(self):
return iter(self.persons)
kotrt = Group('Knights of The Round Table',
[Knight('Launcelot', 'the brave'),
Knight('Galahad', 'the pure'),
Knight('Bedevere', 'the wise'),
Knight('Robin', 'the Not-quite-so-brave-as-Sir-Launcelot')])
for knight in kotrt:
print knight
Lehetőségünk van függvényeket, illetve metódusokat többféle módon meghívni. Ismerjük, hogy hogyan lehet default paraméterértéket megadni.
class A(object):
def __init__(self):
pass
def fuggveny(self):
print "Eredeti fuggveny"
class B(A):
def fuggveny(self, i):
print "B osztaly fuggvenye es", i
class C(A):
def fuggveny(self, i=None):
if i is None:
super(C, self).fuggveny()
else:
print "C osztaly fuggvenye es", i
a = A()
a.fuggveny()
b = B()
b.fuggveny(2)
c1 = C()
c1.fuggveny()
c2 = C()
c2.fuggveny(3)
Írjunk függvényt, ami felveszi a rendelést! Ha nem említjük, hogy mennyit kérünk, akkor úgy érti, hogy egyet.
def order(name, quantity=1):
print name, quantity
order('eggs', 2)
order('spam')
Most megoldjuk, hogy bármennyi különböző terméket rendelhessünk. Használjuk a *argumentumok
formátumú argumentumokat.
def order(name, *args):
print name
for a in args:
print a
order('sausage', 'bacon', 'egg', 'spam')
Ha különböző mennyiségeket akarunk rendelni, akkor másik módszerhez kell folyamodni: használjuk a **argumentumok
formátumú argumentumokat.
def order(*args, **kwargs):
for k in kwargs:
print k, kwargs[k]
order('egg', 'sausage', spam=4)
Vannak olyan esetek, amikor a kód hibába ütközik. Ilyenkor egy Exception típusú objektumot dob a python. Ha senki nem kapja el, akkor a kód megáll futni. Egy Exceptiont bármikor el lehet kapni, akármennyi fügvényhívást túlél. Nézzünk egy példát! Most mi magunk hívjuk elő a hibát, de egyben le is kezeljük.
try:
raise Exception('spam', 'eggs')
except Exception as inst:
print type(inst)
print inst.args
print inst
x, y = inst.args
print 'x =', x
print 'y =', y
Most pedig lekezelünk egy nem mesterségesen létrehozott kivételt.
try:
str(5) + 5
except TypeError as inst:
print type(inst)
print inst.args
print inst
Természetes környezetben. Ha a felhasználó nem egész számot ad, nem tudja azzá konvertálni, így hibát jelez, mi viszont ezt lekezeljük.
while True:
try:
x = int(raw_input("Please enter a number: "))
break
except ValueError:
print "Oops! That was no valid number. Try again..."
print 2*x