Recarga de submódulos en IPython

Actualmente estoy trabajando en un proyecto de Python que contiene submódulos y utiliza numpy / scipy. Ipython se utiliza como consola interactiva. Desafortunadamente, no estoy muy contento con el flujo de trabajo que estoy usando en este momento, agradecería algunos consejos.

En IPython, el marco se carga con un simple comando de import . Sin embargo, a menudo es necesario cambiar el código en uno de los submódulos del marco. En este punto ya hay un modelo cargado y uso IPython para interactuar con él.

Ahora, el marco contiene muchos módulos que dependen unos de otros, es decir, cuando el marco se carga inicialmente, el módulo principal está importando y configurando los submódulos. Los cambios en el código solo se ejecutan si el módulo se reload(main_mod.sub_mod) cargar utilizando reload(main_mod.sub_mod) . Esto es incómodo, ya que necesito volver a cargar todos los módulos modificados individualmente utilizando la ruta completa. Sería muy conveniente si reload(main_module) también recarga todos los submódulos, pero sin recargar numpy / scipy.

IPython viene con algo de magia de recarga automática :

 %load_ext autoreload %autoreload 2 

Volverá a cargar todos los módulos modificados cada vez que se ejecute una nueva línea. La forma en que esto funciona es ligeramente diferente a la dreload . Algunas advertencias aplican, escriba %autoreload? Para ver qué puede salir mal.


Si desea habilitar siempre esta configuración, modifique su archivo de configuración de IPython ~/.ipython/profile_default/ipython_config.py [1] y agregue:

 c.InteractiveShellApp.extensions = ['autoreload'] c.InteractiveShellApp.exec_lines = ['%autoreload 2'] 

Crédito a @Kos a través de un comentario a continuación.

[1] Si no tiene el archivo ~/.ipython/profile_default/ipython_config.py , debe llamar ipython profile create a ipython profile create . O el archivo puede estar ubicado en $IPYTHONDIR .

En IPython 0.12 (y posiblemente antes), puedes usar esto:

 %load_ext autoreload %autoreload 2 

Esto es esencialmente lo mismo que la respuesta de pv. , excepto que la extensión ha sido renombrada y ahora se carga usando %load_ext .

IPython ofrece dreload() para recursivamente recargar todos los submódulos. Personalmente, prefiero usar el comando %run() magic (aunque no realiza una recarga profunda, como lo señala John Salvatier en los comentarios).

Por alguna razón, ni el %autoreload , ni la dreload parecen funcionar para la situación cuando se importa código de una notebook a otra . Sólo funciona la reload Python simple:

 reload(module) 

Basado en [1] .

Qué tal esto:

 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()) 

Esto debería recargar de manera efectiva todo el árbol de módulos y submódulos que le das. También puede poner esta función en su .ipythonrc (creo) para que se cargue cada vez que inicie el intérprete.

http://shawnleezx.github.io/blog/2015/08/03/some-notes-on-ipython-startup-script/

Para evitar escribir esas funciones mágicas una y otra vez, se podrían colocar en el script de inicio de ipython (Nómbrelo con el sufijo .py bajo .ipython / profile_default / startup. Todos los scripts de Python en esa carpeta se cargarán según el orden léxico), que Se parece a lo siguiente:

 from IPython import get_ipython ipython = get_ipython() ipython.magic("pylab") ipython.magic("load_ext autoreload") ipython.magic("autoreload 2") 

Otra opción:

 $ cat << EOF > ~/.ipython/profile_default/startup/50-autoreload.ipy %load_ext autoreload %autoreload 2 EOF 

Verificado en ipython y ipython3 v5.1.0 en Ubuntu 14.04.

Mi práctica estándar para recargar es combinar ambos métodos después de la primera apertura de IPython :

 from IPython.lib.deepreload import reload %load_ext autoreload %autoreload 2 

La carga de módulos antes de hacer esto hará que no se vuelvan a cargar, incluso con una reload(module_name) manual reload(module_name) . Todavía, muy rara vez, tengo problemas inexplicables con los métodos de clase que no se están cargando y que aún no he analizado.

Módulo llamado importlib permite acceder a importaciones internas. Especialmente, proporciona la función importlib.reload() :

 import importlib importlib.reload(my_module) 

A diferencia de %autoreload , importlib.reload() también restablece las variables globales establecidas en el módulo. En la mayoría de los casos, es lo que quieres.

importlib solo está disponible desde Python 3.1. Para versiones anteriores, debes usar el módulo imp .

En Jupyter Notebooks en Anaconda, haciendo esto:

 %load_ext autoreload %autoreload 2 

produjo el mensaje:

La extensión de carga automática ya está cargada. Para recargarlo, usa: %reload_ext autoreload

Parece que es preferible hacer:

 %reload_ext autoreload %autoreload 2 

Información de versión:

La versión del servidor portátil es 5.0.0 y se está ejecutando en: Python 3.6.2 | Anaconda, Inc. | (predeterminado, 20 de septiembre de 2017, 13:35:58) [MSC v.1900 32 bit (Intel)]