Как мне встроить IPython с рабочими выражениями генератора?
Вопрос
Определенные списки не работают должным образом, когда я встраиваю IPython 0.10 в соответствии с инструкциями. Что происходит с моим глобальным пространством имен?
$ 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
Решение 2
Кажется, работает, но IPython считает, что это основная программа. Таким образом, после создания экземпляра IPShell аварийное завершение показывает «упс, аварийный запуск IPython».
import IPython.Shell
ipshell = IPython.Shell.IPShell(argv=[], user_ns={'root':root})
ipshell.mainloop()
Другие советы
Понимание списка в порядке, это работает:
[bar() for i in range(10)]
Это выражения генератора (то, что вы передали этому вызову list ()
), которые не подходят:
gexpr = (bar() for i in range(10))
list(gexpr)
Разница: элементы в понимании списка оцениваются во время определения. Элементы в выражении генератора оцениваются при вызове next ()
(например, через итерацию, когда вы передаете его в list ()
), поэтому он должен сохранять ссылку на область видимости. где это определено. Эта ссылка на область видимо неправильно обрабатывается; скорее всего, это просто ошибка IPython.