¿Cómo incrustar IPython con expresiones generadoras de trabajo?
Pregunta
Ciertas comprensiones de listas no funcionan correctamente cuando incrusto IPython 0.10 según las instrucciones. ¿Qué está pasando con mi espacio de nombres global?
$ 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
Solución 2
Parece funcionar, pero IPython cree que es el programa principal. Entonces, después de crear una instancia de IPShell, un bloqueo muestra "whoops, IPython se bloqueó".
import IPython.Shell
ipshell = IPython.Shell.IPShell(argv=[], user_ns={'root':root})
ipshell.mainloop()
Otros consejos
Las comprensiones de listas están bien, esto funciona:
[bar() for i in range(10)]
Sus expresiones generadoras (que es lo que pasó a esa llamada list ()
) no están bien:
gexpr = (bar() for i in range(10))
list(gexpr)
La diferencia: los elementos en la comprensión de la lista se evalúan en el momento de la definición. Los elementos en la expresión del generador se evalúan cuando se llama a next ()
(por ejemplo, a través de la iteración cuando se pasa a list ()
), por lo que debe mantener una referencia al alcance donde se define Esa referencia de alcance parece tratarse incorrectamente; probablemente sea simplemente un error de IPython.