2016-06-20 30 views
6

Sto utilizzando il rendimento per restituire il valore successivo nella funzione successiva alla nella mia classe. Ma non restituisce il valore successivo, restituisce l'oggetto generatore. Sto cercando di capire meglio gli iteratori e cedere. Potrei farlo nel modo sbagliato. Per favore guarda.quando provo dall'interno __next__. perché restituisce l'oggetto generatore?

class MyString: 
    def __init__(self,s): 
     self.s=s 

    def __iter__(self): 
     return self 

    def __next__(self): 
     for i in range(len(self.s)): 
      yield(self.s[i]) 

r=MyString("abc") 
i=iter(r) 
print(next(i)) 

Ciò restituisce:

generatore oggetto __next__ a 0x032C05A0

+1

['__next__' restituisce il prossimo elemento nell'iteratore] (https://docs.python.org/3/library/stdtypes.html#iterator.__next__) in modo da rendere' __next__' un generatore non ha senso, o bene significa che ogni valore del tuo iteratore 'MyString' è un generatore. –

+2

MyString non dovrebbe definire '__next__'. '__next__' è per gli iteratori, non iterabili. Allo stesso modo, non dovrebbe 'return self' for' __iter__'. – user2357112

risposta

4

next praticamente solo chiama __next__() in questo caso. Chiamando il __next__ sul tuo oggetto, il generatore verrà avviato e restituito (non viene eseguita alcuna magia a questo punto).


In questo caso, si potrebbe essere in grado di farla franca, non definendo __next__ affatto:

class MyString: 
    def __init__(self,s): 
     self.s=s 

    def __iter__(self): 
     for i in range(len(self.s)): 
      yield(self.s[i]) 
     # Or... 
     # for item in self.s: 
     #  yield item 

Se si voleva utilizzare __iter__ e __next__ (per definire un iterator piuttosto che semplicemente facendo un iterable), probabilmente vorrai fare qualcosa del genere:

class MyString: 
    def __init__(self,s): 
     self.s = s 
     self._ix = None 

    def __iter__(self): 
     return self 

    def __next__(self): 
     if self._ix is None: 
      self._ix = 0 

     try: 
      item = self.s[self._ix] 
     except IndexError: 
      # Possibly reset `self._ix`? 
      raise StopIteration 
     self._ix += 1 
     return item 
+0

@MosesKoledoye - Mi stai dicendo di aggiungerlo o di chiedere perché l'ho aggiunto? :-) – mgilson

+0

Non avevo visto la modifica recente. Stavo chiedendo perché mancava –

+1

@MosesKoledoye - Sì, era una svista nel post originale che ho corretto mentre stavi commentando. Ho anche capito che chiamare 'iter (mystring)' probabilmente non dovrebbe resettare l'iterazione ... Grazie per aver guardato la mia schiena. :-) – mgilson