jak „ponownie zaimportować” moduł do Pythona, a następnie zmienić kod po imporcie

92

mam foo.py

def foo():
    print "test"

W IPythonie używam:

In [6]:  import foo
In [7]:  foo.foo()
test

Następnie zmieniłem na foo():

def foo():
    print "test changed"

W IPythonie wynikiem wywołania jest nadal test:

In [10]:  import foo
In [11]:  foo.foo()
test

Następnie używam:

In [15]: del foo
In [16]:  import foo
In [17]:  foo.foo()
test

Usuwam ten foo.pycsam folder foo.py, ale nadal nie mam szczęścia.

Czy mogę wiedzieć, jak ponownie zaimportować zaktualizowany kod w czasie wykonywania?

user478514
źródło

Odpowiedzi:

121

W przypadku Pythona 2.x

reload(foo)

W przypadku Pythona 3.x

import importlib
import foo #import the module here, so that it can be reloaded.
importlib.reload(foo)
John La Rooy
źródło
23
Właściwie po prostu „przeładuj (foo)” - nie ma potrzeby ponownego przypisywania
jsbueno,
2
Nie mogłem sprawić, żeby to zadziałało. Otrzymuję TypeError: argument reload () musi być modułem
Burak
2
@Burak, czy argument, który przekazujesz do reloadmodułu ?. na przykład. Powinieneś to zrobić import foowcześniej
John La Rooy,
27
Zwróć uwagę, że jeśli tak zrobiłeś from foo import *lub from foo import bar, symbol foonie zostanie zdefiniowany. Musisz import syswtedy, reload(sys.modules['foo'])a możereload(sys.modules[bar.__module__])
drevicko
3
Proszę, pozwól Pythonowi 2.x umrzeć asp i przestań wspierać Python 2.x! Odliczanie do wycofania pythona 2.x pythonclock.org .
Martijn van Wezel
66

Oprócz odpowiedzi Gnibblera:

Zmieniło się to w Pythonie 3 na:

>>> import imp
>>> imp.reload(foo)

Jak wskazuje @onnodb, impjest przestarzały na korzyść importlibod wersji 3.4:

>>> import importlib
>>> importlib.reload(foo)
danlei
źródło
5
Mała uwaga: w późniejszych wersjach Pythona 3.x "imp" jest przestarzałe i zastępuje "importlib". Jednak działa w ten sam sposób.
onnodb
56

Funkcja automatycznego ładowania IPython3 działa poprawnie.

Używam rzeczywistego przykładu ze strony internetowej. Najpierw załaduj funkcję „autoreload”.

In []: %load_ext autoreload
In []: %autoreload 2

Następnie zaimportuj moduł, który chcesz przetestować:

In []: import foo
In []: foo.some_function()
Out[]: 42

Otwórz foo.py w edytorze i zmień some_function na powrót 43

In []: foo.some_function()
Out[]: 43

Działa również, jeśli importujesz funkcję bezpośrednio.

In []: from foo import some_function
In []: some_function()
Out[]: 42

Wprowadź zmianę w jakiejś_funkcji, aby zwrócić 43.

In []: some_function()
Out[]: 43
Ashfaq
źródło
1
from foo import some_function, nie działa pod Jupyterlab Python 3.7.3
Robert Nowak
7

Jeśli chcesz, aby działo się to automatycznie, dostępny jest moduł automatycznego ładowania , który jest dostarczany z iPythonem.

CpILL
źródło
from foo import some_function, nie działa pod Jupyterlab Python 3.7.3
Robert Nowak
@Robert Nowak Wpadłem na to, ale zadziałało, gdy próbowałem po prostu "zaimportować jakąś_funkcję" bez "from foo" później w moim kodzie po oryginale z foo import some_function.
Michael Szczepaniak