Como faço para incorporar ipython com expressões de gerador de trabalho?
Pergunta
Certas compreensões da lista não funcionam corretamente quando incorporo o ipython 0.10 conforme as instruções. O que está acontecendo com meu espaço de nome 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
Solução 2
Parece funcionar, mas Ipython acha que é o programa principal. Então, depois de instantar o iPshell, um acidente mostra "gritos, o ipython travou".
import IPython.Shell
ipshell = IPython.Shell.IPShell(argv=[], user_ns={'root':root})
ipshell.mainloop()
Outras dicas
As compreensões da lista são boas, isso funciona:
[bar() for i in range(10)]
São expressões de gerador (que é o que você passou para isso list()
ligue) que não estão bem:
gexpr = (bar() for i in range(10))
list(gexpr)
A diferença: os itens na compreensão da lista são avaliados no horário da definição. Itens na expressão do gerador são avaliados quando next()
é chamado (por exemplo, através da iteração quando você a passa para list()
), portanto, deve manter uma referência ao escopo onde está definido. Essa referência de escopo parece ser tratada incorretamente; Provavelmente, isso é simplesmente um bug ipython.