Recarga de submódulos en IPython


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

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

Ahora, el framework contiene muchos módulos que dependen unos de otros, es decir, cuando el framework 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 vuelve a cargar usando reload(main_mod.sub_mod). Esto es engorroso ya que necesito recargar todos los módulos cambiados individualmente usando la ruta completa. Sería muy conveniente que reload(main_module) también recargara todos los submódulos, pero sin recargar numpy/scipy..

Author: Aaron Hall, 2011-03-19

9 answers

IPython viene con algo de recarga automática magia:

%load_ext autoreload
%autoreload 2

Recargará todos los módulos modificados cada vez antes de ejecutar una nueva línea. La forma en que esto funciona es ligeramente diferente a dreload. Se aplican algunas advertencias, 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 tenga el archivo ~/.ipython/profile_default/ipython_config.py, primero debe llamar a ipython profile create. O el archivo puede estar ubicado en $IPYTHONDIR.

 397
Author: pv.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-25 16:02:04

En IPython 0.12 (y posiblemente anterior), 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.

 23
Author: RafG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:12

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

 18
Author: Sven Marnach,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-21 12:28:40

Por alguna razón, ni %autoreload, ni dreload parecen funcionar para la situación cuando importar código de un cuaderno a otro. Solo Python simple reload funciona:

reload(module)

Basado en [1].

 13
Author: Dennis Golomazov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:46

¿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 efectivamente recargar todo el árbol de módulos y submódulos que le das. También puede poner esta función en su .ipythonrc (creo) por lo que se carga cada vez que se inicia el intérprete.

 3
Author: Y.H Wong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-19 22:27:03

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 poner en el script de inicio de ipython(Nombrarlo con el sufijo .py bajo .ipython / profile_default / startup. Todos los scripts de python bajo esa carpeta se cargarán de acuerdo con 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")
 2
Author: Pegasus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-06 11:48:00

Otra opción:

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

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

 1
Author: Chad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-23 05:04:56

Ejecutar un script en IPython3 no recargaba los módulos cuando usaba el %autoreload magic whatever.

%run my_script.py

# Make changes to `my_module` imported inside `my_script.py`

%load_ext autoreload
%autoreload 2

%run my_script.py

# changes not loaded

Lo siguiente funcionó para mí:

%run my_script.py

# Make changes to `my_module` imported inside `my_script.py`

from IPython.lib.deepreload import reload
reload(my_module_name)

%run my_script.py

# changes correctly loaded
 0
Author: ryanjdillon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-24 12:42:10

En los cuadernos de Jupyter en Anaconda, haciendo esto:

%load_ext autoreload
%autoreload 2

Produjo el mensaje:

La extensión autoreload ya está cargada. Para recargarlo, utilice: %reload_ext autoreload

Parece que Es preferible hacer:

%reload_ext autoreload
%autoreload 2

Información de la versión:

La versión del servidor de notebook es 5.0.0 y se está ejecutando en: Python 3.6.2 / Anaconda, Inc./ (por defecto, Sep 20 2017, 13:35:58) [MSC v. 1900 32 bit (Intel)]

 0
Author: thanks_in_advance,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-26 22:35:02