2012-10-31 6 views
18

Uwielbiam ipython, ale odkryłem problem z% run: importowane moduły nie są ponownie ładowane, gdy% run jest wywoływany wielokrotnie.ipython: ponowne importowanie modułów przy użyciu% run

Załóżmy plik ex1.py zawiera wiersze:

import ex2 
ex2.x.append(1) 
print ex2.x 

i plików ex2.py zawiera:

x = [] 

Teraz działa Pythona ex1.py z linii poleceń wielokrotnie drukuje [1] każdego razu. Ale wywołanie %run ex1.py z poziomu ipythona powoduje wielokrotne wydrukowanie [1], [1,1], [1,1,1] itd. Dzieje się tak, ponieważ moduł ex2.py nie jest ponownie ładowany. Mamy więc problem: protokół skryptu uruchomieniowego ipython nie odzwierciedla zachowania "prawdziwego świata".

Uwaga:

%load_ext autoreload 
%autoreload 2 

robi nie pomocy. Te linie zostaną przeładowane ex2.py tylko wtedy, gdy dokonano zmiany w pliku ex2.py. Jeśli nie wprowadzimy żadnych zmian lub wprowadzimy tylko zmiany w pliku ex1.py, otrzymamy niepożądane zachowanie.

Czy istnieje sposób, aby% run zachowywał się jak wiersz polecenia? To wydaje się być prawdziwym brakiem w używaniu ipython jako środowiska testowego dla skryptów. (A może morał polega na tym, że moduł nie powinien zapisywać w przestrzeni nazw innego modułu?)

Odpowiedz

11

%run ex1.py (lub jakikolwiek skrypt), nie wykonuje głębokiego przeładowania importowanego modułu, nawet jeśli rozszerzenie autoreload jest ustawione na 2 To jest "błąd" w działaniu polecenia %run w ipythonie.

Trzeba będzie jawnie wywołać

dreload(ex2) 

dla głębokiego przeładowania przed wykonaniem %run ex1.py ponownie.

See - http://ipython.org/ipython-doc/dev/api/generated/IPython.lib.deepreload.html

Nie może być plany ustanowienia %run zrobić głęboki przeładować automatycznie w przyszłości i można znaleźć ten problem, który jest nadal kwestią otwartą w tym czasie pisania, jest sugerowane przez użytkownika tutaj - https://github.com/ipython/ipython/issues/461

6

Znam ten sam problem. Wydaje mi się, że jest to niepożądany efekt polecenia uruchomionego przez ipython - nie ładuje ponownie zaimportowanych modułów.

Autor ma rację: Jeśli zmiany zostały dokonane ex2.py następujące polecenie pomoże przeładować

%load_ext autoreload 
%autoreload 2 

Moje Najprostszym sposobem jest poruszać się do modyfikować importowanego moduły (w tym przykładzie , ex2.py) za każdym razem, i wykonaj poniższe polecenia w ipython

%load_ext autoreload 
%autoreload 2 
%run ex1.py 
Pomaga to ponownie załadować plik ex2.py.

Należy pamiętać, że ex2.py musi być modyfikowany za każdym razem przed wykonaniem 3 linii powyżej. Tylko tak można przeładować moduł ex2.