Réimportez un module en python tout en étant interactif


384

Je sais que cela peut être fait, mais je ne me souviens jamais comment.

Comment réimporter un module en python? Le scénario est le suivant: j'importe un module de manière interactive et je le bricole, mais je fais face à une erreur. Je corrige l'erreur dans le fichier .py puis je souhaite réimporter le module fixe sans quitter python. Comment puis-je le faire ?



Réponses:


370

Cela devrait fonctionner:

reload(my.module)

Depuis les documents Python

Rechargez un module précédemment importé. L'argument doit être un objet module, il doit donc avoir été importé avec succès auparavant. Ceci est utile si vous avez édité le fichier source du module à l'aide d'un éditeur externe et que vous souhaitez essayer la nouvelle version sans quitter l'interpréteur Python.

Si vous utilisez Python 3.4 et plus, faites-le import importlib, puis faites-le importlib.reload(nameOfModule).

N'oubliez pas les mises en garde d'utiliser cette méthode:

  • Lorsqu'un module est rechargé, son dictionnaire (contenant les variables globales du module) est conservé. Les redéfinitions de noms remplaceront les anciennes définitions, donc ce n'est généralement pas un problème, mais si la nouvelle version d'un module ne définit pas un nom qui était défini par l'ancienne version, l'ancienne définition n'est pas supprimée.

  • Si un module importe des objets d'un autre module à l'aide from ... import ..., l'appel reload()à l'autre module ne redéfinit pas les objets importés à partir de celui-ci - une façon de contourner cela consiste à réexécuter l' frominstruction, une autre consiste à utiliser importet des noms qualifiés ( module.*name*) à la place.

  • Si un module instancie des instances d'une classe, le rechargement du module qui définit la classe n'affecte pas les définitions de méthode des instances - il continue d'utiliser l'ancienne définition de classe. Il en va de même pour les classes dérivées.


26
si je charge mes modules en utilisant from filename import *. Comment recharger?
Peter Zhu

@PeterZhu pour le cas "from mod import fcn", l'objet module n'est pas ajouté à l'espace de nom. Vous devez donc importer explicitement le module, afin de pouvoir le recharger ultérieurement. import foo; from foo import bar; reload(foo)
Ted

J'ai essayé le rechargement, ainsi que la magie de rechargement automatique, et je vois mon changement de code reflété dans la pile du message d'erreur, mais l'erreur elle-même semble toujours être hors du code périmé (par exemple, la ligne de l'erreur est exactement la même ligne comme précédemment, que j'ai changé en commentaire, et un commentaire ne peut clairement pas être à l'origine d'erreurs). Mon module est chargé en tant qu'extension Jupyter, quelqu'un pourrait-il savoir si cela nécessite un travail différent? Merci!
yifanwu

1
Si vous avez importé votre fonction comme suit "importez le mod en tant que nom", vous devez alors procéder comme suit: 'import importlib importlib.reload (name)'
Noe

Cette méthode peut ne pas remplacer les références des autres modules au module rechargé. Voir stackoverflow.com/a/61617169/2642356 pour une solution à cela.
EZLearner

288

En python 3, reloadn'est plus une fonction intégrée.

Si vous utilisez python 3.4+, vous devez utiliser reloadà la importlibplace à partir de la bibliothèque:

import importlib
importlib.reload(some_module)

Si vous utilisez python 3.2 ou 3.3, vous devez:

import imp  
imp.reload(module)  

au lieu. Voir http://docs.python.org/3.0/library/imp.html#imp.reload

Si vous utilisez ipython, envisagez certainement d'utiliser l' autoreloadextension:

%load_ext autoreload
%autoreload 2

Bien qu'une grande partie du code Python soit écrit en Python 2, Python 3 devient chaque jour une option plus viable. Merci pour le conseil!
Aaron Johnson

40
imp.reloadest obsolète depuis Python 3.4, utilisez plutôt la importlib.reloadfonction .
jfs

1
@Andrew merci! J'ai utilisé le% autoreload, c'est merveilleux, mes objets déjà créés ont automatiquement la mise en œuvre corrigée des méthodes de classe sans avoir à les recréer
jeanmi

4
Je suis un peu en retard, mais je pense que cela ne fonctionne pas si ce que vous devez reload est une fonction ou une classe à l' intérieur du module: si mon statment d'importation était from mymodule import myfunc, alors importlib.reload(myfunc), importlib.reload(mymodule.myfunc), importlib.reload(mymodule)tous donnent une NameError.
Puff

@Puff voir ma réponse ci-dessous pour savoir comment réimporter une fonction
jss367


6

Si vous souhaitez importer une fonction ou une classe spécifique à partir d'un module, vous pouvez le faire:

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

0

Bien que les réponses fournies fonctionnent pour un module spécifique, elles ne rechargeront pas les sous-modules, comme indiqué dans Cette réponse :

Si un module importe des objets à partir d'un autre module à l'aide from ... import ..., l'appel reload()à l'autre module ne redéfinit pas les objets importés à partir de celui-ci - une façon de contourner cela consiste à réexécuter l'instruction from, une autre consiste à utiliser importet des noms qualifiés ( module.*name*) à la place.

Cependant, si vous utilisez la __all__variable pour définir l'API publique, il est possible de recharger automatiquement tous les modules accessibles au public:

# 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)

Les mises en garde notées dans la réponse précédente sont cependant toujours valables. Notamment, la modification d'un sous-module qui ne fait pas partie de l'API publique comme décrit par la __all__variable ne sera pas affectée par un rechargement à l'aide de cette fonction. De même, la suppression d'un élément d'un sous-module ne sera pas reflétée par un rechargement.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.