Je travaille actuellement sur un projet Python contenant des sous-modules et utilisant numpy/scipy. Ipython est utilisé comme console interactive. Malheureusement, je ne suis pas très satisfait du flux de travail que j'utilise actuellement, j'aimerais avoir des conseils.
Dans IPython, la structure est chargée par une simple commande import
. Cependant, il est souvent nécessaire de changer de code dans l’un des sous-modules du cadre. À ce stade, un modèle est déjà chargé et j'utilise IPython pour interagir avec lui.
Le framework contient maintenant de nombreux modules qui dépendent les uns des autres, c'est-à-dire que lorsque le framework est chargé pour la première fois, le module principal importe et configure les sous-modules. Les modifications apportées au code ne sont exécutées que si le module est rechargé à l'aide de reload(main_mod.sub_mod)
. C'est fastidieux car je dois recharger tous les modules modifiés individuellement en utilisant le chemin complet. Il serait très pratique si reload(main_module)
rechargerait également tous les sous-modules, mais sans recharger numpy/scipy ..
IPython est livré avec un rechargement automatique magic:
%load_ext autoreload
%autoreload 2
Il rechargera tous les modules modifiés à chaque fois avant d'exécuter une nouvelle ligne. La façon dont cela fonctionne est légèrement différente de dreload
. Certaines mises en garde s'appliquent, tapez %autoreload?
pour voir ce qui peut mal tourner.
Si vous souhaitez toujours activer ces paramètres, modifiez votre fichier de configuration IPython ~/.ipython/profile_default/ipython_config.py
[1] et ajoutez:
c.InteractiveShellApp.extensions = ['autoreload']
c.InteractiveShellApp.exec_lines = ['%autoreload 2']
Crédit à @Kos via un commentaire ci-dessous.
[1] Si vous n'avez pas le fichier ~/.ipython/profile_default/ipython_config.py
, vous devez d'abord appeler ipython profile create
. Ou le fichier peut être situé à $IPYTHONDIR
.
Dans IPython 0.12 (et peut-être plus tôt), vous pouvez utiliser ceci:
%load_ext autoreload
%autoreload 2
C'est essentiellement la même chose que la réponse de pv. , sauf que l'extension a été renommée et qu'elle est maintenant chargée à l'aide de %load_ext
.
Pour une raison quelconque, ni %autoreload
, ni dreload
ne semblent fonctionner dans la situation où vous importez le code d'un carnet à un autre . Seul Python reload
fonctionne:
reload(module)
Basé sur [1] .
Que dis-tu de ça:
import inspect
# needs to be primed with an empty set for loaded
def recursively_reload_all_submodules(module, loaded=None):
for name in dir(module):
member = getattr(module, name)
if inspect.ismodule(member) and member not in loaded:
recursively_reload_all_submodules(member, loaded)
loaded.add(module)
reload(module)
import mymodule
recursively_reload_all_submodules(mymodule, set())
Cela devrait recharger efficacement l’ensemble de l’arbre de modules et de sous-modules que vous lui donnez. Vous pouvez aussi mettre cette fonction dans votre .ipythonrc (je pense) pour qu’elle soit chargée à chaque démarrage de l’interprète.
http://shawnleezx.github.io/blog/2015/08/03/some-notes-on-ipython-startup-script/
Pour éviter de taper encore et encore ces fonctions magiques, vous pouvez les insérer dans le script de démarrage ipython (nommez-le avec le suffixe .py sous .ipython/profile_default/startup. Tous les scripts python de ce dossier seront chargés selon l'ordre lexical), ressemble à ce qui suit:
from IPython import get_ipython
ipython = get_ipython()
ipython.magic("pylab")
ipython.magic("load_ext autoreload")
ipython.magic("autoreload 2")
Une autre option:
$ cat << EOF > ~/.ipython/profile_default/startup/50-autoreload.ipy
%load_ext autoreload
%autoreload 2
EOF
Vérifié sur ipython et ipython3 v5.1.0 sur Ubuntu 14.04.
Ma pratique habituelle de rechargement consiste à combiner les deux méthodes après la première ouverture de IPython
:
from IPython.lib.deepreload import reload
%load_ext autoreload
%autoreload 2
En chargeant les modules avant cela, ils ne seront pas rechargés, même avec une reload(module_name)
manuelle. J'ai encore, très rarement, des problèmes inexplicables avec des méthodes de classe ne rechargeant pas que je n'ai pas encore examinées.
Le module nommé importlib
permet d’accéder aux internes d’importation. En particulier, il fournit la fonction importlib.reload()
:
import importlib
importlib.reload(my_module)
Contrairement à %autoreload
, importlib.reload()
réinitialise également les variables globales définies dans le module. Dans la plupart des cas, c'est ce que vous voulez.
importlib
n'est disponible que depuis Python 3.1. Pour les versions plus anciennes, vous devez utiliser le module imp
.
Sur Jupyter Notebooks sur Anaconda, procédez comme suit:
%load_ext autoreload
%autoreload 2
produit le message:
L'extension Autoreload est déjà chargée. Pour le recharger, utilisez:
%reload_ext autoreload
Il semble préférable de faire:
%reload_ext autoreload
%autoreload 2
Information sur la version:
La version du serveur de cahiers est 5.0.0 et s'exécute sur: Python 3.6.2 | Anaconda, Inc. | (défaut, le 20 septembre 2017, 13:35:58) [MSC v.1900 32 bits (Intel)]