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.

4voto

Yanqi Huang Points 46

Si vous travaillez dans un environnement jupyter, et que vous disposez déjà de from module import function peut utiliser la fonction magique, autoreload par

%load_ext autoreload
%autoreload
from module import function

L'introduction de la autoreload en IPython est le suivant aquí .

2voto

Ohad Cohen Points 384

En supposant que vous ayez utilisé from X import Y Deux possibilités s'offrent à vous :

reload(sys.modules['X'])
reload(sys.modules[__name__]) # or explicitly name your module

ou

Y=reload(sys.modules['X']).Y

quelques considérations :

A. si la portée de l'importation n'est pas à l'échelle du module (par exemple : importation dans une fonction), vous devez utiliser la deuxième version.

B. si Y est importé dans X à partir d'un autre module (Z) - vous devez recharger Z, puis recharger X et enfin recharger votre module, voire recharger tous vos modules (par exemple : en utilisant [ reload(mod) for mod in sys.modules.values() if type(mod) == type(sys) ] ) pourrait recharger X avant de recharger Z - et donc ne pas actualiser la valeur de Y.

1voto

Denis Otkidach Points 13111
  1. reload() módulo X ,
  2. reload() importation de modules Y de X .

Notez que le rechargement ne modifiera pas les objets déjà créés liés à d'autres espaces de noms (même si vous suivez le guide de style d'Alex).

0voto

Jason S Points 58434

Pour faire suite à ce qui précède, je dirai que AlexMartelli's y Catskul's Il y a des cas très simples, mais désagréables, qui semblent confondre l'efficacité et l'efficience de l'aide. reload du moins dans Python 2.

Supposons que j'aie l'arbre source suivant :

- foo
  - __init__.py
  - bar.py

avec le contenu suivant :

init.py :

from bar import Bar, Quux

bar.py :

print "Loading bar"

class Bar(object):
  @property
  def x(self):
     return 42

class Quux(Bar):
  object_count = 0
  def __init__(self):
     self.count = self.object_count
     self.__class__.object_count += 1
  @property
  def x(self):
     return super(Quux,self).x + 1
  def __repr__(self):
     return 'Quux[%d, x=%d]' % (self.count, self.x)

Cela fonctionne très bien sans utiliser reload :

>>> from foo import Quux
Loading bar
>>> Quux()
Quux[0, x=43]
>>> Quux()
Quux[1, x=43]
>>> Quux()
Quux[2, x=43]

Mais si l'on essaie de recharger, cela n'a aucun effet ou corrompt les choses :

>>> import foo
Loading bar
>>> from foo import Quux
>>> Quux()
Quux[0, x=43]
>>> Quux()
Quux[1, x=43]
>>> reload(foo)
<module 'foo' from 'foo\__init__.pyc'>
>>> Quux()
Quux[2, x=43]
>>> from foo import Quux
>>> Quux()
Quux[3, x=43]
>>> reload(foo.bar)
Loading bar
<module 'foo.bar' from 'foo\bar.pyc'>
>>> Quux()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "foo\bar.py", line 17, in __repr__
    return 'Quux[%d, x=%d]' % (self.count, self.x)
  File "foo\bar.py", line 15, in x
    return super(Quux,self).x + 1
TypeError: super(type, obj): obj must be an instance or subtype of type
>>> Quux().count
5
>>> Quux().count
6
>>> Quux = foo.bar.Quux
>>> Quux()
Quux[0, x=43]
>>> foo.Quux()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "foo\bar.py", line 17, in __repr__
    return 'Quux[%d, x=%d]' % (self.count, self.x)
  File "foo\bar.py", line 15, in x
    return super(Quux,self).x + 1
TypeError: super(type, obj): obj must be an instance or subtype of type
>>> foo.Quux().count
8

La seule façon pour moi de m'assurer que le bar a été rechargé était de reload(foo.bar) ; le seul moyen d'accéder à l'information rechargée sur les Quux est d'aller la chercher dans le sous-module rechargé ; mais la classe foo Le module lui-même a conservé la version originale de la Quux vraisemblablement parce qu'il utilise l'objet de classe from bar import Bar, Quux (plutôt que import bar suivi de Quux = bar.Quux ) ; en outre, le Quux s'est désynchronisée, ce qui est tout simplement bizarre.

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