如何在Jupyter Notebook中使用来自外部Python文件的代码?

时间:2019-06-06 15:51:58

标签: python jupyter-notebook jupyter

我有一个宠物项目,最初是从Jupyter笔记本开始的。到目前为止,我将所有Python代码都放在了笔记本中。

开始时一切都很好。但是随着时间的流逝,我在笔记本中编写的代码变得越来越复杂。现在几乎无法处理:发现错误时,我需要

  1. 使用错误导航到代码部分(通常在笔记本的开头),
  2. 在此处修复错误,
  3. (通常)进入笔记本底部以触发我更改的代码的执行。

我想将代码分为两部分:

  1. 一个将存储为Python文件的文件,我将使用编辑器(和/或IDE)进行编辑。
  2. Jupyter笔记本中的代码将调用代码第1部分并显示其输出(即,将Jupyter笔记本用作步骤1中Python代码的用户界面)。

假设笔记本在我的本地计算机上运行(Windows 7; Jupyter在Anaconda中运行),并且Python文件也存储在本地。

有什么好的方法可以使用IPython文件中的代码,以便我可以频繁,快速地修改此代码?

“经常且快速”的意思是“将更改从Python文件传播到笔记本所需的步骤尽可能少”。理想的解决方案是我更改其中一个Python文件,运行一个命令,然后在Jupyter笔记本中进行更改。或者,使用旧的类比,我希望它像PHP一样-您经常更改代码并立即查看更改的结果。

更新1:我试图在单元格中将%load TestClass.py与该解决方案配合使用。

问题是,如果文件更改,则单元格内容不会更新。

示例:

假设我输入文字

class TestClass:
    def __init__(self):
        print("TestClass constructor")

进入TestClass.py。然后,我在Jupyter笔记本中使用%load TestClass.py创建一个单元格。当我执行该单元格时,将导入TestClass.py中的代码,并将行%load TestClass.py注释掉。

现在我将TestClass.py更改为

class TestClass:
    def __init__(self):
        print("TestClass constructor")
        print("change")

执行单元格时,其内容未更改。

4 个答案:

答案 0 :(得分:4)

IPython的autoload extension之类的声音正是您所需要的。只需插入

%load_ext autoreload
%autoreload 2
在Jupyter笔记本的第一个单元格中的

和导入的python模块会在更改时自动重新加载。如果您已经安装了editable,也可以对已安装的python软件包进行更改。

答案 1 :(得分:0)

我一直在研究类似的问题。如果使用Jupyterlab而不是较旧的Jupyter Notebook,则可以同时打开多个nb,编辑一个保存功能的nb,然后在另一个中重新启动内核以在导入时进行更新。不幸的是,您失去了所有变量,需要再次运行整个笔记本,但是它允许第一个nb中的更改扩展到第二个中。

这不是一个完美的答案,但允许我继续从事我的项目。

答案 2 :(得分:0)

您正在写:

  

和%load TestClass.py行被注释掉。

我了解,您已将其注释掉。为什么?重新运行导入,类将更新。

顺便说一句!运行TestClass.py应该做同样的事情-至少在Jupyter NB中是这样。

答案 3 :(得分:0)

我通常卸载要刷新的模块,然后重新导入。绑定到旧代码的对象不会被刷新,并且我时不时必须重新启动内核,但是它比每次重新启动内核要快得多。对于那些已经了解或愿意了解从sys.modules中删除模块的影响的人,我只建议这样做。但这为我节省了很多时间。

请参见UnloadModules here

我在Jupyter中的典型用法:

from coppertop import Unload
Unload("fred.joe")
from fred.joe.sally import arthur
arthur.doSomethingInteresting()