[英]IPython autoreload changes in subdirectory
I launch IPython from the main folder /project
. 我从主文件夹
/project
启动IPython。 Now if I make changes in the file /project/tests/some_module.py
, the changes fail to be autoreloaded in IPython. 现在,如果我在文件
/project/tests/some_module.py
进行更改,则更改将无法在IPython中自动/project/tests/some_module.py
。 Also, I get the following message after I save the changes and want to run some other script in the prompt: 另外,在保存更改并希望在提示符中运行其他脚本后,我收到以下消息:
[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]
It seems it detects changes were made inside folder /tests
but it cannot import it. 它似乎检测到文件夹
/tests
内部的更改,但它无法导入它。 Can someone help me with this? 有人可以帮我弄这个吗?
Edit: For better clarification: I launch IPython from the terminal in the main folder. 编辑:为了更好地说明:我从主文件夹中的终端启动IPython。 In this folder, I have another folder
tests
. 在这个文件夹中,我有另一个文件夹
tests
。 Inside tests
I have two python files: 内部
tests
我有两个python文件:
some_module.py : some_module.py :
def hello_world():
print "Hello World!!!"
use_some_module.py : use_some_module.py :
from some_module import hello_world
hello_world()
Once I launched IPython, further changes in some_module.py won't be loaded in IPython. 一旦我启动IPython, some_module.py中的进一步更改将不会在IPython中加载。 For example, if I add a second
print "Hello Earth!!!"
例如,如果我添加第二个
print "Hello Earth!!!"
in the definition of hello_world()
, and run run tests/use_some_module.py
, I get the error message shown above, and will only get the "Hello World!!!"
在
hello_world()
的定义中,运行run tests/use_some_module.py
,我得到上面显示的错误信息,只会得到"Hello World!!!"
print. 打印。
Edit2 : I would like a solution where I don't need to either change the working directory, or adding any search paths manually. Edit2 :我想要一个解决方案,我不需要更改工作目录,也不需要手动添加任何搜索路径。 I want it to be loaded automatically with autoreload.
我想让它自动加载自动加载。
If all you need is to reload a changed file in Python just do the following: 如果您只需要在Python中重新加载已更改的文件,请执行以下操作:
from main import some_module
....
reload(some_module)
But if your reload purposes are really eager, you can do the following (taken from this question ): 但如果您的重新加载目的非常迫切,您可以执行以下操作(取自此问题 ):
%load_ext autoreload
%autoreload 2
The previous code will reload all changed modules every time before executing a new line. 之前的代码将在执行新行之前每次重新加载所有已更改的模块。
NOTE: You can also check dreload which does a recursive reload of a module, and %run which allows you to run any python script and load all of its data directly into the interactive namespace. 注意:您还可以检查执行模块递归重载的dreload ,以及允许您运行任何python脚本并将其所有数据直接加载到交互式命名空间的%run 。
Hope it helps, 希望能帮助到你,
Try changing your file use_some_module.py
to: 尝试将文件
use_some_module.py
更改为:
import some_module
some_module.hello_world()
Reload with from import
usually does not work. from import
重新加载通常不起作用。
This works for me: 这对我有用:
%autoreload 1
%aimport use_some_module
%aimport some_module
Module /project/tests/some_module.py
must be importable from /project
. 模块
/project/tests/some_module.py
必须可从/project
导入。 It means /project/tests
must be in sys.path
. 这意味着
/project/tests
必须在sys.path
。
Either change to /project/tests
and %run use_some_module.py
or do sys.path.insert(0,tests)
to insert tests
into module search path. 更改为
/project/tests
和%run use_some_module.py
或执行sys.path.insert(0,tests)
以将tests
插入模块搜索路径。
If some_module
is not in search path, IPython's autoreload
never gonna find it. 如果
some_module
不在搜索路径中,则IPython的autoreload
永远不会找到它。
Another way to make it work is to make the tests
a package by creating __init__.py
in it. 另一种使其工作的方法是通过在其中创建
__init__.py
来使tests
成为一个包。 And use relative import in use_some_module
as from .some_module import hello_world
. 并使用
use_some_module
相对导入,如from .some_module import hello_world
。 Now do these from IPython prompt, 现在从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!!!
That's you have to run use_some_module
module in the tests
package as a script. 那就是你必须在
tests
包中运行use_some_module
模块作为脚本。
The first time you do %run tests/use_some_module.py
, which is run as if you were running python tests/use_some_module.py
. 第一次执行
%run tests/use_some_module.py
,它就像运行python tests/use_some_module.py
运行。 So /project/tests
which the script is in, is automatically included in sys.path
. 所以脚本所在的
/project/tests
会自动包含在sys.path
。 That's why from some_module import hello_world
in use_some_module
succeeds. 这就是为什么
from some_module import hello_world
在use_some_module
成功。 Additionally, after the run, objects in use_some_module
's global namespace are available in IPython session. 此外,在运行之后,
use_some_module
的全局命名空间中的对象在IPython会话中可用。
But when you change tests/some_module
, it has to be loaded again to see the changes. 但是当你更改
tests/some_module
,必须再次加载它才能看到更改。 To reload
it manually, it has to be imported first. 要手动
reload
,必须先导入它。 Now import
should succeed because use_some_module
imported it first when it was run, some_module
is in sys.modules
. 现在
import
应该成功,因为use_some_module
在运行时use_some_module
导入它, some_module
在sys.modules
。 But reload
to succeed, some_moudle
has to be in search path. 但
reload
成功, some_moudle
必须处于搜索路径。 So, even manual reload
would fail let alone autoreload
. 所以,即便是手动
reload
会失败更不用说autoreload
。
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
Another solution is to start IPython as PYTHONPATH=tests ipython
to include tests
directory in sys.path
. 另一个解决方案是启动IPython,因为
PYTHONPATH=tests ipython
以包含sys.path
tests
目录。
Or set this c.InteractiveShellApp.exec_lines = ['import sys','sys.path.insert(0,"tests")']
in ipython_config.py
. 或设置该
c.InteractiveShellApp.exec_lines = ['import sys','sys.path.insert(0,"tests")']
中ipython_config.py
。
. 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.