605 votos

¿Cómo puedo descargar (recargar) un módulo de Python?

Tengo un tiempo de ejecución de Python server y me gustaría ser capaz de actualizar un servicio sin reiniciar el servidor. ¿Cuál es la mejor manera de hacer esto?

if foo.py has changed:
    unimport foo  <-- How do I do this?
    import foo
    myfoo = foo.Foo()

553voto

cdleary Puntos 18869

Puede volver a cargar un módulo, cuando ya ha sido importados por el uso de la recarga función integrada:

import foo

while True:
    # Do some things.
    if is_changed(foo):
        foo = reload(foo)

Creo que esto es lo que usted desea. Servidores Web como Django desarrollo del servidor este modo que usted puede ver los efectos de sus cambios de código sin necesidad de reiniciar el servidor propio proceso.

A la cita de la documentación:

Los módulos de Python' código se vuelve a compilar y el código de nivel de módulo puede volver a ejecutar, la definición de un nuevo conjunto de objetos que están obligados a nombres en el módulo del diccionario. La inicialización de la función de los módulos de extensión no es llamado segundo tiempo. Como con todos los demás objetos en Python los objetos antiguos son sólo recuperado tras sus recuentos de referencia caen a cero. Los nombres en el módulo de espacio de nombres se actualizan a punto para cualquier nuevo o modificado en los objetos. Otros las referencias a los objetos antiguos (tales como nombres externos al módulo) no rebote para referirse a los objetos nuevos y debe ser actualizado en cada espacio de nombres donde ocurrir si se desea.

Como señaló en su pregunta, usted tendrá que reconstruir Foo a los objetos, si la Foo clase reside en la foo módulo.

231voto

Paul D. Waite Puntos 35456

En Python 3.0-3.3: imp.reload(module)

El BDFL ha respondido a esta pregunta.

Sin embargo, imp estaba en desuso en la versión 3.4, en favor de importlib (gracias @Stefan!).

Yo creo que, por lo tanto, tendría que utilizar ahora importlib.reload(module), aunque no estoy seguro.

75voto

Gregg Lind Puntos 6905

Puede ser especialmente difícil para eliminar un módulo, si no es Python puro.

Aquí es cierta información de: ¿Cómo puedo eliminar realmente un módulo importado?

Usted puede utilizar sys.getrefcount() para conocer el número real de referencias.

>>> import sys, empty, os
>>> sys.getrefcount(sys)
9
>>> sys.getrefcount(os)
6
>>> sys.getrefcount(empty)
3

Los números de mayor a 3 indican que va a ser duro para deshacerse de la módulo. Los canteranos "vacío" (contiene nada) módulo debe ser el recolector de basura después de

>>> del sys.modules["empty"]
>>> del empty

la tercera referencia es un artefacto de la getrefcount() función.

57voto

bobince Puntos 270740

reload(módulo), pero sólo si es totalmente independiente. Si nada más tiene una referencia para el módulo (o cualquier objeto perteneciente al módulo), a continuación, que obtendrá sutil y curiosos errores causados por el viejo código colgando alrededor más de lo esperado, y cosas como isinstance no funciona a través de diferentes versiones de un mismo código.

Si usted tiene una forma dependencias, también debe volver a cargar todos los módulos que dependen de los vuelve a cargar el módulo de deshacerse de todas las referencias al antiguo código. Y, a continuación, volver a cargar los módulos que dependen de la recarga de los módulos, de forma recursiva.

Si usted tiene dependencias circulares, lo cual es muy común, por ejemplo, cuando usted está tratando de volver a cargar un paquete, debe descargar todos los módulos en el grupo de una sola vez. Usted no puede hacer esto con reload() porque va a volver a importar cada módulo antes de sus dependencias se han actualizado, lo que permite antiguas referencias a la fluencia en módulos nuevos.

La única manera de hacerlo en este caso es hackear sys.modules, que es una especie de no admitidos. Tendrías que ir a través de y eliminación de cada uno de sys.modules entrada que quería ser recargada en la siguiente importación, y también eliminar las entradas, cuyos valores son None para lidiar con un problema de implementación que ver con cacheing error relativo de las importaciones. No es terriblemente bonita, pero siempre y cuando usted tiene un auto-contenida conjunto de dependencias que no deja de referencias fuera de su código base, es viable.

Es probablemente la mejor manera de reiniciar el servidor. :-)

52voto

Kumaresan Puntos 269
if 'myModule' in sys.modules:  
    del(sys.modules["myModule"]) 

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: