Cómo recargar el módulo de python importado usando ' from module import`'


Vi en esta útil pregunta que se puede usar reload(whatever_module) o, en Python 3, imp.reload(whatever_module).

Mi pregunta es, ¿y si hubiera dicho from whatever_module import * importar? Entonces no tengo whatever_module al que hacer referencia cuando uso reload(). ¿Van a gritarme por lanzar un módulo entero al espacio de nombres global? :)

Author: Community, 2011-04-01

6 answers

Estoy de acuerdo con el "no hagas esto generalmente" consenso, pero...

La respuesta correcta es:

import X
reload(X)
from X import Y  # or * for that matter
 41
Author: Catskul,
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-08-01 16:02:54

Nunca use import *; destruye la legibilidad.

Además, tenga en cuenta que recargar módulos casi nunca es útil. No puede predecir en qué estado terminará su programa después de recargar un módulo, por lo que es una gran manera de obtener errores incomprensibles e irreproducibles.

 8
Author: Allen,
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-04-01 17:42:29

A

from module import *

Toma todos los objetos "exportados" de module y los enlaza a nombres de nivel de módulo (o lo que sea que su ámbito sea). Usted puede recargar el módulo como:

reload(sys.modules['module'])

Pero eso no le hará ningún bien: los nombres de nivel de cualquiera que sea su alcance todavía apuntan a los objetos antiguos.

 3
Author: tzot,
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-06-10 17:46:05

Al importar usando from whatever_module import whatever, whatever se cuenta como parte del módulo de importación, por lo que para recargarlo, debe recargar su módulo. Pero con solo recargar tu módulo todavía obtendrás el antiguo whatever - del ya importado whatever_module, por lo que necesitas recargar (whatever_module), y luego recargar tu módulo:

# reload(whatever_module), if you imported it
reload(sys.modules['whatever_module'])
reload(sys.modules[__name__])

Si usaste from whatever_module import whatever también puedes considerar

whatever=reload(sys.modules['whatever_module']).whatever

O

whatever=reload(whatever_module).whatever
 0
Author: Ohad Cohen,
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-08-18 22:15:25

Una respuesta más limpia es una mezcla de la buena respuesta de Catskul y el uso de Ohad Cohen de sys.module y la redefinición directa:

import sys
Y = reload(sys.module["X"]).Y  # reload() returns the new module

De hecho, hacer import X crea un nuevo símbolo (X) que podría ser redefinido en el código que sigue, lo cual es innecesario (mientras que sys es un módulo común, por lo que esto no debería suceder).

El punto interesante aquí es que from X import Y no agrega X al espacio de nombres, sino que agrega module X a la lista de módulos conocidos (sys.modules), lo que permite que el módulo sea reloaded (and its new contents accessed).

Más generalmente, si es necesario actualizar varios símbolos importados, entonces es más conveniente importarlos de esta manera:

import sys
reload(sys.module["X"])  # No X symbol created!
from X import Y, Z, T
 0
Author: Eric Lebigot,
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-08-01 16:26:28
import re

for mod in sys.modules.values():
    if re.search('name', str(mod)):
        reload(mod)
 -1
Author: jennifer,
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-11-06 06:25:27