Come posso incorporare IPython con espressioni di generatore funzionanti?
Domanda
Alcune comprensioni dell'elenco non funzionano correttamente quando ho incorporato IPython 0.10 secondo le istruzioni. Cosa sta succedendo con il mio spazio dei nomi globale?
$ python
>>> import IPython.Shell
>>> IPython.Shell.IPShellEmbed()()
In [1]: def bar(): pass
...:
In [2]: list(bar() for i in range(10))
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/tmp/<ipython console>
/tmp/<ipython console> in <generator expression>([outmost-iterable])
NameError: global name 'bar' is not defined
Soluzione 2
Sembra funzionare, ma IPython pensa che sia il programma principale. Quindi, dopo aver istanziato IPShell, un crash mostra "whoops", IPython si è bloccato ".
import IPython.Shell
ipshell = IPython.Shell.IPShell(argv=[], user_ns={'root':root})
ipshell.mainloop()
Altri suggerimenti
La comprensione dell'elenco va bene, funziona:
[bar() for i in range(10)]
Sono le espressioni del generatore (che è ciò che hai passato a quella lista ()
chiamata) che non vanno bene:
gexpr = (bar() for i in range(10))
list(gexpr)
La differenza: gli elementi nella comprensione dell'elenco vengono valutati al momento della definizione. Gli elementi nell'espressione del generatore vengono valutati quando viene chiamato next ()
(ad es. Tramite iterazione quando lo si passa a list ()
), quindi deve mantenere un riferimento all'ambito dove è definito. Tale riferimento di ambito sembra essere gestito in modo errato; molto probabilmente è semplicemente un bug di IPython.