Quando foo()
restituisce un normale iterabile, i due sono equivalenti. La "magia" entra in gioco quando foo()
è un generatore . In quel momento, i casi yield from foo()
e for x in foo(): yield x
differiscono materialmente.
Un generatore può essere inviato dati, utilizzando il generator.send()
method. Quando si utilizza il ciclo for
, l'espressione yield x
"riceve" i dati inviati; il generatore foo()
non vedrà mai questo. Ma quando si utilizza yield from
i dati inviati vanno direttamente a qualsiasi espressione yield
il generatore delegato è attualmente in pausa a. In altre parole, yield from
passa i dati inviati in modo che il generatore delegato possa riceverlo.
È inoltre possibile aumentare le eccezioni in un generatore, con generator.throw()
; con il caso di loop for
, l'eccezione viene sollevata dalla riga yield x
, mentre con yield from
l'eccezione viene nuovamente inoltrata; l'eccezione viene sollevata all'interno di foo()
.
Insieme, ciò significa che yield from
nella sostanza sostituisce il generatore corrente per la durata dell'iterazione delegata.
Il delegato-al generatore ottiene anche per comunicare con il generatore genitore, quando fatto l'attributo .value
di eccezione StopIteration
sollevata viene restituito come valore della yield from
espressione. È possibile impostare il valore di tale eccezione utilizzando return <expression>
nel generatore delegato a foo()
oppure è possibile utilizzare raise StopIteration(<expression>)
in modo esplicito.
yield from
è stato introdotto nella lingua con PEP 380: Syntax for Delegating to a Subgenerator.
fonte
2014-09-17 12:40:12
Vedere [PEP-380] (http://legacy.python.org/dev/peps/pep-0380/). – jonrsharpe
Domanda correlata: http://stackoverflow.com/questions/24033577/difference-between-generator-expression-and-generator-function – Bakuriu