132 votes

Python : recharger le composant Y importé avec "from X import Y" ?

En Python, une fois que j'ai importé un module X dans une session de l'interpréteur à l'aide de import X et que le module change à l'extérieur, je peux recharger le module avec reload(X) . Les modifications sont 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 à l'aide de from X import Y .

La déclaration reload Y ne fonctionne pas, car Y n'est pas un module en soi, mais seulement un composant (dans ce cas, une classe) à l'intérieur d'un module.

Est-il possible de recharger des composants individuels d'un module sans quitter la session de l'interpréteur (ou sans importer le module entier) ?

EDITAR:

Pour plus de clarté, la question porte sur l'importation d'un fichier classe ou fonction Y d'un module X et le rechargement lors d'un changement, et non un module Y d'un paquet X.

137voto

Catskul Points 3600

Réponse

D'après mes tests, la réponse marquée, qui suggère une simple reload(X) ne fonctionne pas.

D'après ce que j'ai pu constater, la bonne réponse est la suivante :

from importlib import reload # python 2.7 does not require this
import X
reload( X )
from X import Y

Test

Mon test était le suivant (Python 2.6.5 + bpython 0.9.5.2)

X.py :

def Y():
    print "Test 1"

bpython :

>>> from X import Y
>>> print Y()
Test 1
>>> # Edit X.py to say "Test 2"
>>> print Y()
Test 1
>>> reload( X )  # doesn't work because X not imported yet
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'X' is not defined
>>> import X
>>> print Y()
Test 1
>>> print X.Y()
Test 1
>>> reload( X ) # No effect on previous "from" statements
>>> print Y()
Test 1
>>> print X.Y() # first one that indicates refresh
Test 2
>>> from X import Y
>>> print Y()
Test 2 
>>> # Finally get what we were after

55voto

Alex Martelli Points 330805

Si Y est un module (et X un paquet) reload(Y) sera parfait - sinon, vous comprendrez pourquoi les bons guides de style Python (comme celui de mon employeur) disent qu'il faut nunca importer quoi que ce soit sauf un module (c'est l'une des nombreuses bonnes raisons - et pourtant les gens continuent d'importer des fonctions et des classes directement, même si j'ai beau leur expliquer que c'est no une bonne idée;-).

27voto

user3361281 Points 1
from modulename import func

import importlib, sys
importlib.reload(sys.modules['modulename'])
from modulename import func

6voto

wisty Points 4280

Tout d'abord, vous ne devriez pas utiliser la recharge, 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 ramènera pas les noms dans l'espace de noms du module. Pour ce faire, il suffit de réaffecter les variables :

f = open('zoo.py', 'w')
f.write("snakes = ['viper','anaconda']\n")
f.close()

from zoo import snakes
print snakes

f = open('zoo.py', 'w')
f.write("snakes = ['black-adder','boa constrictor']\n")
f.close()

import zoo
reload(zoo)
snakes = zoo.snakes # the variable 'snakes' is now reloaded

print snakes

Il y a plusieurs façons de procéder. Vous pourriez automatiser le processus en cherchant dans l'espace de noms local et en réaffectant tout ce qui provient du module en question, mais je pense que nous sommes assez méchants.

4voto

Chris Fryer Points 711

Si vous voulez le faire :

from mymodule import myobject

Faites plutôt ceci :

import mymodule
myobject=mymodule.myobject

Vous pouvez maintenant utiliser myobject de la même manière que vous l'aviez prévu (sans les fastidieuses références illisibles à mymodule).

Si vous travaillez de manière interactive et que vous souhaitez recharger mon objet à partir de mon module, vous pouvez maintenant utiliser :

reload(mymodule)
myobject=mymodule.myobject

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X