Reimporte um módulo em python enquanto interativo


383

Eu sei que isso pode ser feito, mas nunca me lembro como.

Como você pode reimportar um módulo em python? O cenário é o seguinte: Eu importo um módulo interativamente e mexo nele, mas então enfrento um erro. Corrijo o erro no arquivo .py e quero reimportar o módulo fixo sem sair do python. Como eu posso fazer isso ?



Respostas:


369

Isso deve funcionar:

reload(my.module)

Dos documentos do Python

Recarregue um módulo importado anteriormente. O argumento deve ser um objeto de módulo, portanto, deve ter sido importado com sucesso antes. Isso é útil se você editou o arquivo de origem do módulo usando um editor externo e deseja experimentar a nova versão sem sair do interpretador Python.

Se você estiver executando o Python 3.4 ou superior, import importlibfaça importlib.reload(nameOfModule).

Não se esqueça das advertências de usar este método:

  • Quando um módulo é recarregado, seu dicionário (contendo as variáveis ​​globais do módulo) é mantido. As redefinições de nomes substituirão as definições antigas, portanto isso geralmente não é um problema, mas se a nova versão de um módulo não definir um nome definido pela versão antiga, a definição antiga não será removida.

  • Se um módulo importa objetos de outro módulo usando from ... import ..., chamar reload()o outro módulo não redefine os objetos importados - uma maneira de contornar isso é reexecutar a frominstrução, outra é usar importnomes qualificados ( module.*name*).

  • Se um módulo instancia instâncias de uma classe, recarregar o módulo que define a classe não afeta as definições de método das instâncias - elas continuam usando a definição de classe antiga. O mesmo vale para classes derivadas.


26
se eu carregar meus módulos usando from filename import *. Como recarregar?
— Peter Zhu

@PeterZhu para o caso "from mod import fcn", o objeto do módulo não é adicionado ao espaço de nome. Portanto, você precisa importar explicitamente o módulo para poder recarregá-lo posteriormente. import foo; from foo import bar; reload(foo)
— Ted

Tentei recarregar, assim como a mágica de carregamento automático, e vejo minha alteração de código refletida na pilha da mensagem de erro, mas o erro em si ainda parece estar fora do código obsoleto (por exemplo, a linha do erro está exatamente na mesma linha como antes, que mudei para um comentário e um comentário claramente não pode estar causando erros). Meu módulo está carregado como uma extensão Jupyter. Alguém pode saber se isso requer uma solução alternativa diferente? Obrigado!
— yifanwu

11
Se você importou sua função da seguinte forma "import mod as name", precisará fazer o seguinte: 'import importlib importlib.reload (name)'
— Noe

Este método pode não substituir as referências de outros módulos para o módulo recarregado. Consulte stackoverflow.com/a/61617169/2642356 para obter uma solução para isso.
— EZLearner

288

No python 3, reloadnão é mais uma função integrada.

Se você estiver usando o python 3.4+, você deve usar a reloadpartir da importlibbiblioteca:

import importlib
importlib.reload(some_module)

Se você estiver usando python 3.2 ou 3.3, deverá:

import imp  
imp.reload(module)  

em vez de. Consulte http://docs.python.org/3.0/library/imp.html#imp.reload

Se você estiver usando ipython, definitivamente considere usar a autoreloadextensão:

%load_ext autoreload
%autoreload 2

Embora muitos códigos do Python sejam escritos no Python 2, o Python 3 está se tornando uma opção mais viável todos os dias. Obrigado pela dica!
— Aaron Johnson

40
imp.reloadé preterido desde Python 3.4, usar importlib.reloadfunção vez.
— JFS

11
@Andrew thanks! Eu usei o autoreload%, é maravilhoso, meus objetos já criados ficou automaticamente a implementação corrigido dos métodos de classe sem ter que recriá-los
— jeanmi

4
Eu sou um pouco tarde, mas acho que isso não funciona se o que você precisa de recarga é uma função ou classe de dentro do módulo: se meu statment importação foi from mymodule import myfunc, então importlib.reload(myfunc), importlib.reload(mymodule.myfunc), importlib.reload(mymodule)todos dão uma NameError.
— Puff

@ Puff, veja minha resposta abaixo para saber como reimportar uma função
— jss367 30/03


6

Se você deseja importar uma função ou classe específica de um módulo, você pode fazer isso:

import importlib
import sys
importlib.reload(sys.modules['my_module'])
from my_module import my_function

0

Embora as respostas fornecidas funcionem para um módulo específico, elas não recarregam os submódulos, conforme observado em Esta resposta :

Se um módulo importa objetos de outro módulo usando from ... import ..., chamar reload()o outro módulo não redefine os objetos importados - uma maneira de contornar isso é reexecutar a instrução from, outra é usar importnomes qualificados ( module.*name*).

No entanto, se estiver usando a __all__variável para definir a API pública, é possível recarregar automaticamente todos os módulos disponíveis ao público:

# Python >= 3.5
import importlib
import types


def walk_reload(module: types.ModuleType) -> None:
    if hasattr(module, "__all__"):
        for submodule_name in module.__all__:
            walk_reload(getattr(module, submodule_name))
    importlib.reload(module)


walk_reload(my_module)

As advertências observadas na resposta anterior ainda são válidas. Notavelmente, a modificação de um submódulo que não faz parte da API pública, conforme descrito pela __all__variável, não será afetada por um recarregamento usando esta função. Da mesma forma, a remoção de um elemento de um submódulo não será refletida por uma recarga.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.