在Jupyter Notebook中使用%% time在连续单元格中更改变量范围

gus*_*coh 4 python scope numpy jupyter-notebook

TL; DR

我面临一个奇怪的问题(或者我缺少一些基本的知识)。我有一个Jupyter笔记本,在一个单元格中有一个另存为的变量numpy.ndarray,但是当我在下一个单元格中打印其类型时,该变量显示为type list。这怎么可能?在我的机器上工作正常,在VM中没有。


详细说明:

我正在处理某个请求请求,以更新Jupyter笔记本,并且由于我在当前设置中遇到一些绘图问题,因此我尝试在具有更新程序包和组件的其他机器/系统上对其进行测试。

在我的笔记本电脑中,我具有Ubuntu 16.04和以下配置:

> The version of the notebook server is: 5.7.4 The server is running on
> this version of Python: Python 3.5.2 (default, Nov 12 2018, 13:43:14) 
> [GCC 5.4.0 20160609]
> 
> Current Kernel Information: Python 3.5.2 (default, Nov 12 2018,
> 13:43:14)
> IPython 7.2.0 -- An enhanced Interactive Python. Type '?' for help.
Run Code Online (Sandbox Code Playgroud)

我创建了一个虚拟机,安装了Ubuntu 18.04,并使用以下配置:

> The version of the notebook server is: 5.7.6 The server is running on
> this version of Python: Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
> [GCC 8.2.0]
> 
> Current Kernel Information: Python 3.6.7 (default, Oct 22 2018, 11:32:17)
> IPython 7.4.0 -- An enhanced Interactive Python. Type '?' for help.
Run Code Online (Sandbox Code Playgroud)

然后,我确定的是,在虚拟机中,变量从改变其类型numpy.ndarraylist,没有理由(对我来说)。变量是pos。这给我造成了问题,因为以后将其用于索引目的

笔记本电脑:

笔记本电脑

虚拟机: 虚拟机

这里发生了什么?我在这方面缺少什么吗?

任何提示表示赞赏:)谢谢。


更新:

我已经在VM中尝试了另一个笔记本,现在不仅仅是改变类型,还没有在其他单元格(变量joint_vars)中到达变量:

在此处输入图片说明

VM中的环境是否应该配置错误?

小智 6

我相信这里的问题是细胞魔术处理范围的变化。您的笔记本电脑正在运行IPython 7.2.0;您的VM正在运行7.4.0。旧行为在7.4.0中已更改(这可能是在以后的版本中修复的错误)。

我怀疑pos先前已将其定义为笔记本中的列表。在7.4.0中(如在您的VM上),单元中的所有内容均视为本地范围。例如:

Python 3.7.2 | packaged by conda-forge | (default, Mar 19 2019, 20:46:22)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.4.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: foo = "bar"

In [2]: foo
Out[2]: 'bar'

In [3]: %%time
   ...: foo = 5
   ...:
   ...:
CPU times: user 3 µs, sys: 1 µs, total: 4 µs
Wall time: 5.72 µs

In [4]: foo
Out[4]: 'bar'
Run Code Online (Sandbox Code Playgroud)

如果您在7.3.0中运行相同的内容,则最终会得到

In [4]: foo
Out[4]: 5
Run Code Online (Sandbox Code Playgroud)

由于foo先前已定义为字符串,因此您观察到的效果是foo(从4单元格开始)类型的变化取决于IPython的版本。(在这里,应该是整数,然后更改为字符串。)当所涉及的类型密切相关时(例如您的情况下的列表和numpy数组),这将更加微妙。不是因为单元而改变了类型;因为从未分配新值,所以它保留了旧类型。

解决方案是暂时将虚拟机降级到IPython 7.3.0,或者避免使用%%time单元魔术。