Sono Iteratori creati ad-hoc dal programmatore, praticamente sono delle CLASSI che implementano almeno i due metodi __iter__() e __next__()
nel metodo __iter__() Avviene l’inizializzazione dell’iteratore e il suo return (di solito viene ritornato l’oggetto stesso)
nel metodo __next__() ritorna il prossimo elemento nella sequenza e solleva l’eccezione StopIteration alla fine degli elementi
Facciamo un esempio di un iteratore che ad ogni chiamata restituise il valore precedente aumentato di 1.44 partendo da 0
class numeri:
#inizializzo l'iteratore partendo da 0
def __iter__(self):
self.x = 0
return self
#calcolo valore successivo restituito ad ogni chimata next(<oggetto>)
def __next__(self):
a = self.x
self.x += 1.44
return round(a,2)
oggetto = numeri()
#converto in iteratore
test = iter(oggetto)
#scorro iteratore
for i in range(0,100):
print(next(test))
I commenti al codice dicono tutto, l’unica cosa e’ che questo iteratore non finira’ mai di generare in quanto nella dichiarazione del metodo __next__() non c’e’ limite, pertanto lanciando un for i in range(oggetto) il ciclo durerebbe all’infinito. Se ad esempio volessimo fermare la generazione al numero superiore a 144.00 dovremmo modificare il codice nel modo seguente:
class numeri:
def __iter__(self):
self.x=0
return self
def __next__(self):
a = self.x
self.x +=1.44
if(a <= 144):
return round(a,2)
else:
StopIteration
oggetto = numeri()
test = iter(oggetto)
for i in range (0,120):
print(next(test))
In fine vediamo un esempio di iteratore customizzato con la possibilita’ di passergli dei parametri (esempio range(0,100):
class numeriDispari(object):
def __init__(self, max):
self.max = max #imposto il valore massimo
self.n = -1 #imposto la partenza che sara sempre 1
def __next__(self):
self.n += 2 #incremeto di 2 il valore precedente
( all inizio self.n = -1, quindi self.n + 2 = 1)
if self.n > self.max:
raise StopIteration #se supero il valore max fermo l'iterazione
else:
return self.n #altrimenti rimando il valore calcolato
def __iter__(self):
return self
#stampo i primi 10 numeri dipsari
numeri = numeriDispari(10)
for n in numeri:
print(n)
#creo una lista dei primi 80 numeri dipari
numeri_d = [ x for x in numeriDispari(100) if x < 80]
print(numeri_d)
I commentio nel codice spiegano il funzionamento
