Írunk egy Person osztályt. Minden embernek lesz neve és titulusa, a __str__ 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. A leszármazott örökli az ősosztály összes tagváltozóját és metódusát.
class Person:
    def __init__(self, name, title):
        self.name = name
        self.title = title
    def __str__(self):
        return self.title + " " + self.name
class Knight(Person):
    def __init__(self, name):
        super().__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 opcionális epitheton ornansa!
class Person:
    def __init__(self, name, title):
        self.name = name
        self.title = title
    def __str__(self):
        return self.title + " " + self.name
class Knight(Person):
    def __init__(self, name, eo=""):
        super().__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 felüldefiniáljuk a __str__ 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:
    def __init__(self, name, title):
        self.name = name
        self.title = title
    def __str__(self):
        return self.title + " " + self.name
class Knight(Person):
    def __init__(self, name, eo=""):
        super().__init__(name, 'Sir')
        self.eo = eo
    def __str__(self):
        if len(self.eo) > 0:
            return self.title + " " + self.name + ", " + self.eo
        else:
            return super().__str__()
         
launcelot = Knight('Launcelot', 'the brave')
black = Knight('Black')
robin = Knight('Robin', 'the Not-quite-so-brave-as-Sir-Launcelot')
print(launcelot)
print(black)
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.
Hogy ne essen egybe a Person title változójával, nevezzük special_title-nak.
Ahhoz, hogy az osztályszintű változót elérjük, a Knight.special_title-ra kell hivatkozni, de bármelyik példány .special_title változója is erre mutat.
class Person:
    def __init__(self, name, title):
        self.name = name
        self.title = title
    def __str__(self):
        return self.title + " " + self.name
class Knight(Person):
    special_title = 'Sir'
    def __init__(self, name, eo=""):
        super().__init__(name, "")
        self.eo = eo
    def __str__(self):
        return Knight.special_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(robin.special_title, launcelot.special_title, Knight.special_title)
Megjegyezzük, hogy az öröklési lánc tetszőlegesen hosszú lehet, illetve lehet egyszerre több osztályból örökölni.
Vannak olyan esetek, amikor a kód hibába ütközik. Ilyenkor egy Exception típusú objektumot dob (emel) a Python.
Ekkor
Kivéve, ha
try:
        ...
    except ... :
        ...
Egy Exception-t bármikor el lehet kapni, akármennyi függvényhívást túlél. Nézzünk egy példát! Most mi magunk hívjuk elő a hibát (raise), 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)
Lássunk egy természetes példát! Olvassunk be egy valós számot és írjuk ki a kétszeresét! Ha a felhasználó nem valós számot ad, a float() nem tudja azzá konvertálni, így hibát jelez, mi viszont ezt lekezeljük.
while True:
    try:
        x = float(input("Adjon meg egy valós számot: "))
        break
    except ValueError:
        print("Hoppá! Ez nem valós szám, próbálja újra!")
print(2*x)
Nézzük meg hogy hol történt a kivétel dobása (raise) és hol az elkapása.
def f(x):
    return x + 5 # nem jó ha x egy string
def g(x):
    return x + x # ez jó int-re és str-re is
x = "5"
y = g(x)
z = f(y)
def beolvas(n):
    maximum = float("-inf")
    for i in range(n):
        x = float(input())
        if x > maximum:
            maximum = x
    return maximum
try:
    y = beolvas(3)
    print(y)
except ValueError as e:
    print(e)
Írhatunk saját kivétel osztályt is, ezt arra tudjuk használni, hogy egyedi hibákat jelezzünk vele.
Csupán az Exception beépített osztályból kell öröklődni (opcionálisan mást is lehet bele rakni).
class KnightException(Exception):
    pass
try:
    lancelot = Person("Lancelot", "Mr")
    x = str(lancelot)
    if x[:3] != "Sir":
        raise KnightException("Use correct title")    
except KnightException as s:
    print(s)
Láttuk, hogy a for i in L nem csak akkor működik, ha L lista.
Pontosan mely objektumok állhatnak a for ... in után?
A for meghívja az iter() függvényt, mellyel hozzájut az iterátorhoz (bejáró). Ebben definiálva van egy __next__() metódus, 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.
Iterátor az az objektum, aminek van __next__() metódusa.
Minden iterátor objektum egyúttal iterálható objektum. Fordítva ez nem áll. A lista iterálható, de nem iterátor. 
for ... in után iterálható objektum állhat, aminek van __iter__() metódusa, ami iterátor objektumot ad vissza. Ezek meghívhatók függvényként: x.__iter__() ekvivalens az iter(x), x.__next__() a next(x) hívással.
Ezek speciális metódusok!
r = range(3)    # iterálható (bejárható)
print(type(r))
it = iter(r)    # iterátor (bejáró)
print(type(it))
next(it)
print(next(it))
print(next(it))
next(it)
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átor, ez jelzi az iterálás kezdetét. Az iterátor objektumok definiálnak egy __next__() metódust, ami sorban visszaadja az elemeket.
Ha kifogyott, akkor StopIteration kivételt emel.
class Person:
    def __init__(self, name, title=""):
        self.name = name
        self.title = title
    def __str__(self):
        return self.title + " " + self.name
class Knight(Person):
    title = 'Sir'
    searching_for = 'The Holy Grail'
    def __init__(self, name, eo):
        super().__init__(name)
        self.eo = eo
    def __str__(self):
        return Knight.title + " " + self.name + ", " + self.eo    
class Group:
    def __init__(self, name, persons):
        self.persons = persons
        self.name = name
        
    def __iter__(self):
        self.index = 0
        return self
    
    def __next__(self):
        if self.index >= len(self.persons):
            raise StopIteration     # dobunk egy kivételt
        self.index += 1
        return self.persons[self.index - 1]
        
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)
Mindezt megoldhatjuk egyszerűbben a listát mint bejárható objektumot használva:
class Group:
    def __init__(self, name, persons):
        self.persons = persons
        self.name = name
    def __iter__(self): # A Group csoportot iterálhatóvá tesszük
        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:  # a ciklus lefut egy Group objektumra
    print(knight)
Ha a Group objektumot nem tesszük bejárhatóvá, akkor még mindig kiírhatjuk egy csoport összes személyét, hisz a .persons tagváltozó lista (de ez már nem olyan elegáns):
class Group:
    def __init__(self, name, persons):
        self.persons = persons
        self.name = name
        
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.persons: # kotrt nem, de kotrt.persons bejárható
    print(knight)