Írunk egy Person osztályt. Minden embernek lesz neve és titulusa, majd a __repr__
megszólítjuk az illetőt. 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ának ö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')
launcelot = Knight('Launcelot')
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')
print 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
-re kell hivatkozni. A searching_for
azonban már úgy viselkedik, ahogyan szeretnénk.
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
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. Tetszőleges, általunk definiált objektumra is megoldható. 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:
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
self.index = 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
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
self.index = -1
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. Í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.
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.
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..."