Comment recharger un module de fonction en Python?
Suivi cette question concernant le rechargement d'un module, comment puis-je recharger une fonction spécifique dans une changé module?
pseudo-code:
from foo import bar
if foo.py has changed:
reload bar
Vous devez vous connecter pour publier un commentaire.
Ce que vous voulez, c'est possible, mais nécessite un rechargement de deux choses... d'abord
reload(foo)
, mais alors vous devez égalementreload(baz)
(en supposant quebaz
est le nom du module contenant lafrom foo import bar
déclaration).Pourquoi... Quand
foo
est chargée pour la première fois, unfoo
objet est créé, contenant unbar
objet. Lorsque vous importez desbar
dans lebaz
module, il stocke une référence àbar
. Lorsquereload(foo)
est appelée, lefoo
objet est effacé, et le module de ré-exécuté. Cela signifie que tous lesfoo
références sont toujours valables, mais une nouvellebar
objet a été créé... pour toutes les références qui ont été importés, quelque part, sont encore des références à la vieuxbar
objet. En rechargeantbaz
, vous la cause de réimporter la nouvellebar
.Alternativement, vous pouvez simplement faire
import foo
dans votre module, et toujours faire appel àfoo.bar()
. De cette façon, chaque fois que vousreload(foo)
, vous obtiendrez le plus récentbar
de référence.À compter d'aujourd'hui, la bonne façon de le faire est:
Testé sur python 2.7, 3.5, 3.6.
Chaud de rechargement n'est pas quelque chose que vous pouvez faire en Python de manière fiable, sans exploser votre tête. Vous ne peuvent littéralement pas de support de rechargement sans écrire de code particulière, et en essayant d'écrire et de maintenir un code qui prend en charge le rechargement avec toute la santé mentale exige une discipline de fer et est trop confus pour être en vaut la peine. Tests de code de ce type n'est pas facile non plus.
La solution est de redémarrer complètement le Python processus lorsque le code a changé. Il est possible de le faire de façon transparente, mais la façon dont dépend votre problème spécifique de domaine.
reload
quais, dire la même chose.importlib.reload()
fonctionne très bien et est idéal pour les dev. Suffit de savoir comment il fonctionne, n'ont pas eu de problèmes avec elle.Alors que le rechargement des fonctions n'est pas une caractéristique de la
reload
fonction, il est encore possible. Je ne recommande pas de le faire dans la production, mais voici comment cela fonctionne:La fonction que vous souhaitez remplacer un objet quelque part dans la mémoire, et votre code peut contenir plusieurs références à celui-ci (et non pas le nom de la fonction). Mais ce que la fonction ne fait lorsque l'appel n'est pas enregistré dans l'objet, mais dans un autre objet qui, à son tour, est référencé par la fonction de l'objet, dans son attribut
__code__
. Donc, tant que vous avez une référence à la fonction, vous pouvez mettre à jour son code:Module mymod:
D'autres modules /python session:
Maintenant, dans le cas où vous n'avez pas une référence à l'ancienne fonction (c'est à dire un
lambda
passé dans une autre fonction), vous pouvez essayer de les attraper avec lagc
module, par la recherche de la liste de tous les objets:Vous ne pouvez pas recharger une méthode à partir d'un module, mais vous pouvez charger le module avec un nouveau nom, dire
foo2
et direbar = foo2.bar
de remplacer la référence actuelle.Noter que si
bar
a des dépendances sur d'autres choses dansfoo
effets secondaires ou d'autres, vous allez avoir des ennuis. Ainsi, alors qu'il travaille, il ne fonctionne que pour la plupart des cas simples.Vous devrez utiliser
reload
pour recharger le module, puisque vous ne pouvez pas recharger simplement la fonction:reload(foo)
,bar
serait pas modifier. Ce aurait arriver, c'est subtil et déroutant, il est donc préférable de simplement de ne jamais utiliserreload
ou de tenter de faire chaud, rechargement de code en Python. Votre santé mentale et de fiabilité merci.exit
si vousfrom sys import exit
puis changersys.exit
puisimport sys
etreload(sys)
?sys
ce n'est même pas possible.)from ... import ...
!reload
est pas des conseils utiles.Si vous êtes l'auteur de
foo.py
, vous pouvez écrire:Puis, dans votre pseudo, recharger si
bar.py
a changé. Cette approche est particulièrement agréable lorsque la barre de vie dans le même module que le code qui veut à chaud recharger plutôt que de l'OP cas où il vit dans un autre module.