Certain list comprehensions don't work properly when I embed IPython 0.10 as per the instructions. What's going on with my global namespace?
$ python
>>> import IPython.Shell
>>> IPython.Shell.IPShellEmbed()()
In [1]: def 开发者_JS百科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
List comprehensions are fine, this works:
[bar() for i in range(10)]
It's generator expressions (which is what you passed to that list()
call) that are not fine:
gexpr = (bar() for i in range(10))
list(gexpr)
The difference: items in the list comprehension are evaluated at definition time. Items in the generator expression are evaluated when next()
is called (e.g. through iteration when you pass it to list()
), so it must keep a reference to the scope where it is defined. That scope reference seems to be incorrectly handled; most probably that's simply an IPython bug.
Seems to work, but IPython thinks it's the main program. So after instantiating IPShell, a crash shows "whoops, IPython crashed".
import IPython.Shell
ipshell = IPython.Shell.IPShell(argv=[], user_ns={'root':root})
ipshell.mainloop()
For this situation, I've found the following updates the scope so that bar()
can be found:
globals().update(locals())
精彩评论