IPython自动加载子目录中的更改

IPython自动加载子目录中的更改,python,ipython,Python,Ipython,我从主文件夹/project启动IPython。现在,如果我在文件/project/tests/some_module.py中进行更改,这些更改将无法在IPython中自动恢复。此外,在保存更改并希望在提示符中运行其他脚本后,我会收到以下消息: [autoreload of some_module failed: Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/IPython/extensio

我从主文件夹
/project
启动IPython。现在,如果我在文件
/project/tests/some_module.py
中进行更改,这些更改将无法在IPython中自动恢复。此外,在保存更改并希望在提示符中运行其他脚本后,我会收到以下消息:

[autoreload of some_module failed: Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/IPython/extensions/autoreload.py", line 229, in check
    superreload(m, reload, self.old_objects)
ImportError: No module named some_module]
它似乎检测到文件夹
/tests
中的更改,但无法导入。有人能帮我吗

编辑: 为了更好的说明:我从主文件夹中的终端启动IPython。在这个文件夹中,我有另一个文件夹
tests
。在
测试中
我有两个python文件:

某些模块.py

def hello_world():
  print "Hello World!!!"
from some_module import hello_world

hello_world()
使用一些模块.py

def hello_world():
  print "Hello World!!!"
from some_module import hello_world

hello_world()
一旦我启动了IPython,某些_module.py中的进一步更改将不会加载到IPython中。例如,如果我在
Hello\u world()
的定义中添加第二个
打印“Hello Earth!!!”
,然后运行
运行测试/use\u some\u module.py
,我会得到上面显示的错误消息,并且只会得到
打印的“Hello world!!!”


Edit2:我想要一个不需要更改工作目录或手动添加任何搜索路径的解决方案。我希望它能通过autoreload自动加载。

如果您只需要在Python中重新加载更改过的文件,只需执行以下操作:

from main import some_module
....
reload(some_module)
但是,如果您的重新加载目的非常迫切,您可以执行以下操作(摘自):

以前的代码将在每次执行新行之前重新加载所有更改的模块

注意:您还可以检查哪个模块进行递归重新加载,哪个模块允许您运行任何python脚本并将其所有数据直接加载到交互式命名空间中


希望有帮助,

尝试将文件
使用\u some\u module.py更改为:

import some_module

some_module.hello_world()
使用导入的
重新加载通常不起作用

这对我很有用:

%autoreload 1
%aimport use_some_module
%aimport some_module

模块
/project/tests/some_Module.py
必须可从
/project
导入。这意味着
/project/tests
必须位于
sys.path

In [2]: #before %run  
In [3]: 'some_module' in globals()
Out[3]: False

In [6]: 'some_module' in sys.modules
Out[6]: False

In [7]: 'hello_world' in globals()
Out[7]: False

In [8]: run tests/use_some_module.py
Hello World!!!

In [9]: 'some_module' in globals()
Out[9]: False

In [11]: 'some_module' in sys.modules
Out[11]: True

In [12]: 'hello_world' in globals()
Out[12]: True
In [13]: import some_module

In [14]: some_module = reload(some_module)
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-14-47e3c0de23e1> in <module>()
----> 1 some_module = reload(some_module)

ImportError: No module named some_module
更改为
/project/tests
%run使用某些模块.py
或执行
sys.path.insert(0,tests)
测试插入模块搜索路径

如果某个模块不在搜索路径中,IPython的
autoreload
将永远找不到它

另一种方法是通过在
中创建
\uuu init\uuuuu.py
使
测试成为一个包。并在
中使用相对导入,使用部分模块作为
来源。部分模块导入hello\u world
。现在从IPython提示符执行这些操作

In [1]: load_ext autoreload

In [2]: %autoreload 2

In [3]: from tests import some_module

In [4]: run -m tests.use_some_module
Hello World!!!
In [5]: ed tests/some_module.py
"tests/some_module.py" 3L, 69C written
 done. Executing edited code...
In [6]: run -m tests.use_some_module
Hello World!!!
Hello World!!!  
也就是说,您必须以脚本的形式运行
测试
包中的
使用部分模块
模块

第一次执行
%运行测试/使用某些模块.py
,运行时就像运行
python测试/使用某些模块.py
一样。因此脚本所在的
/project/tests
会自动包含在
sys.path
中。这就是为什么
从某个模块导入hello\u world
使用某个模块
成功的原因。此外,在运行之后,
中的对象使用一些模块的全局名称空间,这些对象在IPython会话中可用

但是,当您更改
测试/某些模块时,必须再次加载它才能查看更改。要手动重新加载它,必须先导入它。现在,
导入
应该会成功,因为
使用某些模块
在运行时首先导入,
某些模块
位于
系统模块
中。但是
reload
要成功,
必须在搜索路径中找到一些moude
。因此,即使手动重新加载也会失败,更不用说自动加载了

In [2]: #before %run  
In [3]: 'some_module' in globals()
Out[3]: False

In [6]: 'some_module' in sys.modules
Out[6]: False

In [7]: 'hello_world' in globals()
Out[7]: False

In [8]: run tests/use_some_module.py
Hello World!!!

In [9]: 'some_module' in globals()
Out[9]: False

In [11]: 'some_module' in sys.modules
Out[11]: True

In [12]: 'hello_world' in globals()
Out[12]: True
In [13]: import some_module

In [14]: some_module = reload(some_module)
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-14-47e3c0de23e1> in <module>()
----> 1 some_module = reload(some_module)

ImportError: No module named some_module
[2]中的
:#在%run之前
[3]中:globals()中的“some_module”
Out[3]:False
[6]中:sys.modules中的“some_module”
Out[6]:假
在[7]中,globals()中的“hello_world”
Out[7]:假
在[8]中:运行测试/使用某个模块.py
你好,世界!!!
[9]中:globals()中的“some_module”
Out[9]:假
[11]中:sys.modules中的“some_module”
Out[11]:对
在[12]中,globals()中的“hello_world”
Out[12]:对
在[13]中:导入一些_模块
[14]中:某些_模块=重新加载(某些_模块)
---------------------------------------------------------------------------
ImportError回溯(最近一次呼叫最后一次)
在()
---->1部分模块=重新加载(部分模块)
ImportError:没有名为某个\u模块的模块
另一种解决方案是将IPython作为
PYTHONPATH=tests IPython
启动,以将
tests
目录包含在
sys.path

或者在
ipython\u config.py
中设置此
c.InteractiveShellApp.exec\u lines=['import sys','sys.path.insert(0,“tests”)]

.

您第一次如何导入模块?您是否在首次导入和重新加载之间更改了工作目录?@michael在您的Edit2中,出现错误
ImportError:No module named some_module
意味着,
autoreload
模块的
superreload
功能找不到
some_模块
,因为
some_模块
不在搜索路径中。@NizamMohamed如果我退出ipython并在同一父目录中重新启动它,更改会被更新。@NizamMohamed So,我想让它在每次
tests/
发生更改时自动执行。我已经在我的ipython配置文件中添加了
autoreload 2
,它在我启动ipython的同一目录中执行更改操作,但它无法在子目录中执行更改操作。我想要一个解决方案,我可以添加到我的ipython配置文件中,以便它自动执行。我已经更新了我的答案。不走运。你能重复我的问题吗?谢谢你的回答。我是Python新手,所以我不确定是否完全理解它。为什么autoreload不够聪明,无法在同一条路径上查找