En Python, une fois que j'ai importé un module X dans une session d'interpréteur en utilisant import X
, et que le module change à l'extérieur, je peux recharger le module avec reload(X)
. Les modifications deviennent alors disponibles dans ma session d'interprétation.
Je me demande si cela est également possible lorsque j'importe un composant Y du module X en utilisant from X import Y
.
L'instruction reload Y
ne fonctionne pas, puisque Y n'est pas un module lui-même, mais seulement un composant (dans ce cas une classe) à l'intérieur d'un module.
Est-il possible du tout de recharger des composants individuels d'un module sans quitter la session d'interprétation (ou importer le module entier)?
ÉDITER:
Pour clarifier, la question concerne l'importation d'une classe ou d'une fonction Y depuis un module X et le rechargement sur un changement, pas un module Y depuis un package X.
la source
... possible ... import a component Y from module X
" vs "question is ... importing a class or function X from a module Y
". J'ajoute une modification à cet effet.Réponses:
Si Y est un module (et X un paquet)
reload(Y)
sera bien - sinon, vous verrez pourquoi les bons guides de style Python (comme mon employeur de) disent ne rien importer sauf un module (ce qui est l' une de plusieurs bonnes raisons - pourtant les gens continuent d'importer directement des fonctions et des classes, peu importe combien j'explique que ce n'est pas une bonne idée ;-).la source
import this
depuis l'invite interactive pour voir le Zen of Python); et toutes les raisons pour lesquelles les espaces de noms sont une excellente idée (indices visuels locaux immédiats que le nom est recherché, facilité de se moquer / injecter dans les tests, capacité de recharger, capacité pour un module de changer de manière flexible en redéfinissant certaines entrées, prévisible et contrôlable comportement sur la sérialisation et la récupération de vos données [[par exemple par décapage et décapage]], et ainsi de suite, et ainsi de suite - un commentaire SO est à peine assez long pour rendre justice à ce riche et long argument !!! -)importlib
package.importlib.reload(Y)
docs.python.org/3.4/library/… voir aussi stackoverflow.com/questions/961162/...Répondre
D'après mes tests, la réponse marquée, qui suggère un simple
reload(X)
, ne fonctionne pas.D'après ce que je peux dire, la bonne réponse est:
Tester
Mon test était le suivant (Python 2.6.5 + bpython 0.9.5.2)
X.py:
bpython:
la source
Foo
qui a un__init__.py
qui récupère un sous-module ... Je posterai une réponse comme contre-exemple.la source
Tout d'abord, vous ne devriez pas du tout utiliser le rechargement, si vous pouvez l'éviter. Mais supposons que vous ayez vos raisons (c'est-à-dire le débogage dans IDLE).
Le rechargement de la bibliothèque ne récupérera pas les noms dans l'espace de noms du module. Pour ce faire, réaffectez simplement les variables:
Vous pouvez le faire de plusieurs autres façons. Vous pouvez automatiser le processus en recherchant dans l'espace de noms local et en réaffectant tout ce qui provenait du module en question, mais je pense que nous sommes assez méchants.
la source
Si vous voulez faire ceci:
Faites ceci à la place:
Vous pouvez maintenant utiliser myobject de la même manière que vous l'aviez prévu (sans les références mymodule illisibles fastidieuses partout).
Si vous travaillez de manière interactive et que vous souhaitez recharger myobject à partir de mymodule, vous pouvez désormais utiliser:
la source
en supposant que vous avez utilisé
from X import Y
, vous avez deux options:ou
quelques considérations:
A. si la portée de l'importation n'est pas à l'échelle du module (e, g: importation dans une fonction) - vous devez utiliser la deuxième version.
B. si Y est importé dans X depuis un autre module (Z) - vous devez recharger Z, puis recharger X et que recharger votre module, même recharger tous vos modules (e, g: using
[ reload(mod) for mod in sys.modules.values() if type(mod) == type(sys) ]
) pourrait recharger X avant de recharger Z - et que pas rafraîchir la valeur de Y.la source
reload()
moduleX
,reload()
module importéY
depuisX
.Notez que le rechargement ne changera pas les objets déjà créés liés dans d'autres espaces de noms (même si vous suivez le guide de style d'Alex).
la source
Si vous travaillez dans un environnement Jupyter et que vous l'avez déjà fait, vous
from module import function
pouvez utiliser la fonction magique,autoreload
enL'introduction du
autoreload
dans IPython est donnée ici .la source
Juste pour faire suite aux réponses d'AlexMartelli et de Catskul , il y a des cas vraiment simples mais désagréables qui semblent confondre
reload
, du moins dans Python 2.Supposons que j'ai l'arborescence des sources suivante:
avec le contenu suivant:
init.py:
bar.py:
Cela fonctionne très bien sans utiliser
reload
:Mais essayez de recharger et cela n'a aucun effet ou corrompt les choses:
La seule façon dont je pouvais m'assurer que le
bar
sous - module était rechargé était dereload(foo.bar)
; la seule façon d'accéder à laQuux
classe rechargée est de l'atteindre et de la récupérer dans le sous-module rechargé; mais lefoo
module lui-même a continué à conserver l'Quux
objet de classe d' origine , probablement parce qu'il utilisefrom bar import Bar, Quux
(plutôt queimport bar
suivi parQuux = bar.Quux
); de plus, laQuux
classe s'est désynchronisée avec elle-même, ce qui est tout simplement bizarre.la source