Подтвердить что ты не робот

Изменения в автозагрузке IPython в подкаталоге

Я запускаю IPython из основной папки /project. Теперь, если я вношу изменения в файл /project/tests/some_module.py, изменения не будут автоматически загружены в IPython. Кроме того, после сохранения изменений я получаю следующее сообщение и хочу запустить в командной строке еще один script:

[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, но он не может ее импортировать. Может кто-нибудь помочь мне с этим?

Edit: Для лучшего уточнения: я запускаю IPython из терминала в основной папке. В этой папке у меня есть другая папка tests. Внутри tests У меня есть два файла python:

some_module.py

def hello_world():
  print "Hello World!!!"

use_some_module.py

from some_module import hello_world

hello_world()

Как только я запустил IPython, дальнейшие изменения в some_module.py не будут загружены в IPython. Например, если я добавлю второй print "Hello Earth!!!" в определение hello_world() и запустив run tests/use_some_module.py, я получу сообщение об ошибке, показанное выше, и вы получите только печать "Hello World!!!".

Edit2. Я хотел бы получить решение, в котором мне не нужно либо изменять рабочий каталог, либо добавлять какие-либо пути поиска вручную. Я хочу, чтобы он загружался автоматически с помощью автозагрузки.

4b9b3361

Ответ 1

Если вам нужно только перезагрузить измененный файл в Python, выполните следующие действия:

from main import some_module
....
reload(some_module)

Но если ваши задачи перезагрузки действительно интересны, вы можете сделать следующее (взятое из этого вопроса):

%load_ext autoreload
%autoreload 2

Предыдущий код будет перезагружать все измененные модули каждый раз перед выполнением новой строки.

ПРИМЕЧАНИЕ. Вы также можете проверить dreload, который выполняет рекурсивную перезагрузку модуля, и % run, который позволяет запускать любой python script и загружать все свои данные непосредственно в интерактивное пространство имен.

Надеюсь, что это поможет,

Ответ 2

Попробуйте изменить файл use_some_module.py на:

import some_module

some_module.hello_world()

Перезагрузка с from import обычно не работает.

Это работает для меня:

%autoreload 1
%aimport use_some_module
%aimport some_module

Ответ 3

Модуль /project/tests/some_module.py должен быть импортирован из /project. Это означает, что /project/tests должен быть в sys.path.

Перейдите в /project/tests и %run use_some_module.py или выполните sys.path.insert(0,tests), чтобы вставить tests в путь поиска модуля.

Если some_module не находится в пути поиска, IPython autoreload никогда не найдет его.

Другой способ заставить его работать - сделать пакет tests, создав в нем __init__.py. И используйте относительный импорт в use_some_module как from .some_module import hello_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!!!  

Чтобы запустить use_some_module модуль в пакете tests как script.

В первый раз вы выполняете %run tests/use_some_module.py, который запускается, как если бы вы выполняли python tests/use_some_module.py. Итак, /project/tests, в котором находится script, автоматически включается в sys.path. Вот почему from some_module import hello_world в use_some_module преуспевает. Кроме того, после запуска в сеансе IPython доступны объекты в глобальном пространстве имен use_some_module.

Но когда вы меняете tests/some_module, его нужно снова загрузить, чтобы увидеть изменения. Для reload он вручную, он должен быть импортирован первым. Теперь import должен преуспеть, потому что use_some_module импортировал его сначала, когда он был запущен, some_module находится в sys.modules. Но reload для успеха, some_moudle должен находиться в пути поиска. Таким образом, даже ручная 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

Другим решением является запуск IPython как PYTHONPATH=tests ipython для включения каталога tests в sys.path.
Или установите этот c.InteractiveShellApp.exec_lines = ['import sys','sys.path.insert(0,"tests")'] в ipython_config.py.
.