como "reimportar" o módulo para python e o código ser alterado após a importação

87

eu tenho um foo.py

def foo():
    print "test"

No IPython eu uso:

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

Então mudei foo()para:

def foo():
    print "test changed"

No IPython, o resultado da invocação ainda é test:

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

Então eu uso:

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

Apago o foo.pycna mesma pasta foo.pyexiste, mas ainda sem sorte.

Posso saber como reimportar o código atualizado em tempo de execução?

user478514
fonte
2
Possível duplicata de Reimportar um módulo em python enquanto interativo
Praveen

Respostas:

116

Para Python 2.x

reload(foo)

Para Python 3.x

import importlib
import foo #import the module here, so that it can be reloaded.
importlib.reload(foo)
John La Rooy
fonte
23
Na verdade, apenas "recarregar (foo)" - não há necessidade de atribuí-lo
novamente
2
Eu não conseguia fazer funcionar. Estou obtendo TypeError: o argumento reload () deve ser módulo
Burak
2
@Burak, o argumento que você está passando é reloadum módulo ?. por exemplo. Você deveria estar fazendo de import fooantemão
John La Rooy
27
Observe que se você fez from foo import *ou from foo import bar, o símbolo foonão é definido. Você precisa import sysentão reload(sys.modules['foo'])ou talvezreload(sys.modules[bar.__module__])
drevicko
3
Por favor, deixe o Python 2.x morrer asp e pare de suportar o Python 2.x! Uma contagem regressiva para a aposentadoria de python 2.x pythonclock.org .
Martijn van Wezel
65

Além da resposta do gnibbler:

Isso mudou no Python 3 para:

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

Como @onnodb aponta, impestá obsoleto importlibdesde o Python 3.4:

>>> import importlib
>>> importlib.reload(foo)
danlei
fonte
5
Apenas uma pequena nota: nas versões posteriores do Python 3.x, "imp" foi substituído por "importlib". Funciona da mesma maneira, no entanto.
onnodb
54

O recurso autoreload do IPython3 funciona perfeitamente.

Estou usando o exemplo real da página da web. Primeiro carregue o recurso 'autoreload'.

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

Em seguida, importe o módulo que deseja testar:

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

Abra foo.py em um editor e altere some_function para retornar 43

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

Também funciona se você importar a função diretamente.

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

Faça a alteração em some_function para retornar 43.

In []: some_function()
Out[]: 43
Ashfaq
fonte
1
from foo import some_function, não funcionando em Jupyterlab Python 3.7.3
Robert Nowak
7

Se você quiser que isso aconteça automaticamente, existe o módulo autoreload que vem com o iPython.

CpILL
fonte
from foo import some_function, não funcionando em Jupyterlab Python 3.7.3
Robert Nowak