2014-04-10 10 views
5

Giocando intorno con alberi, mi sono imbattuto su questo comportamento:vuoto generatore

def descendants (self): 
    return #or "pass" or "42" 

restituisce ovviamente None.

D'altro lato:

def descendants (self): 
    return 
    yield 42 

restituisce un generatore che produce niente (in realtà il comportamento che mi serviva per nodi foglia).

Qualcuno potrebbe spiegarmi cosa sta succedendo sotto il cofano qui?

Il codice yield 42 non dovrebbe essere irraggiungibile? (Suppongo che la decisione se una funzione sia un generatore o una funzione "normale" venga eseguita in fase di compilazione, a seconda che contenga una o varie affermazioni yield, siano esse raggiungibili o meno. Ma questo è solo uno sparo nell'oscurità .)


Il contesto è il seguente: Ho alberi e ogni nodo è un albero o una foglia. Ora voglio generare tutti i discendenti di un nodo:

class Leaf (Node): 
    @property 
    def descendants (self): 
     return 
     yield 42 

class Tree (Node): 
    @property 
    def descendants (self): 
     for child in self.children: 
      yield child 
      yield from child.descendants 
+0

Io di solito solo 'return()', poiché agisce come un generatore vuoto. – U2EF1

risposta

4

A quanto mi risulta, la parola chiave yield all'interno di una funzione viene rilevato al momento della compilazione. Il risultato è che la funzione non si comporta più come una normale funzione. Quando viene chiamata una funzione con una parola chiave yield, la funzione IMMEDIATELY restituisce un oggetto generatore pigro che produce le variabili necessarie in base alla funzione definita. Il codice nella tua funzione viene eseguito solo quando il generatore viene iterato.

E 'più succintamente spiegato here.

Così descendants si chiama, e dal momento che la parola chiave yield è presente nella funzione, un oggetto generatore è immediatamente restituito. Dal descendants immediatamente return s, tuttavia, il generatore non produce valori, ma è sicuramente ancora un generatore.

+0

Grazie per il link. Ho trovato la domanda collegata, ma non è riuscito a scorrere fino alla risposta che hai collegato. Fammi digerire questo un po '. – Hyperboreus

+0

Hai qualche link ai documenti di lingua, in quanto questo non dice nulla: https://docs.python.org/3.4/tutorial/classes.html#generators – Hyperboreus

+0

@JesseMu +1 Hai reso la spiegazione pulita e accurata . –