2009-10-04 27 views
26

Esta es una pregunta muy básica, pero no he podido encontrar una respuesta buscando en línea.python refresh/reload

Estoy usando python para controlar ArcGIS, y tengo un script de python simple, que llama a un código pre-escrito.

Sin embargo, cuando realizo un cambio en el código preescrito, no parece dar lugar a ningún cambio. Importe este módulo y he intentado actualizarlo, pero no pasa nada.

Incluso he movido el archivo que llama a otra ubicación, y la secuencia de comandos todavía funciona bien. Una cosa que hice ayer fue que agregué la carpeta donde están todos mis archivos python a la ruta del sistema (usando sys.append ('ruta')), y me pregunto si eso marcó la diferencia.

Gracias de antemano, y disculpe por la terminología descuidada.

Respuesta

31

No está claro a qué se refiere con "refresh", pero el comportamiento normal de Python es que es necesario reiniciar el software para él para echar un nuevo vistazo a un módulo de Python y volver a leerlo.

Si los cambios no se toma el cuidado de incluso después de reiniciar, entonces esto se debe a uno de dos errores:

  1. La marca de tiempo en el PYC-archivo es incorrecto y en algún momento en el futuro.
  2. En realidad está editando el archivo incorrecto.

Puede volver a cargar volver a leer un archivo incluso sin reiniciar el software con el comando reload(). Tenga en cuenta que cualquier variable que señale algo en el módulo deberá ser reimportada después de la recarga. Algo como esto:

import themodule 
from themodule import AClass 

reload(themodule) 
from themodule import AClass 
+0

Tuve un problema similar y esto funcionó. Me di cuenta de que eliminar el primer 'de la AClass de importación de los módulos sigue siendo el truco. ¿Alguna razón para tener ambos? – pentandrous

+0

No es realmente "un truco" para resolver un problema, y ​​su problema real proviene de otro lugar. Deberías tratar de resolver eso en su lugar. –

19

Una forma de hacerlo es llamar al reload.

Ejemplo: Aquí está el contenido de foo.py:

def bar(): 
    return 1 

En una sesión interactiva, que puedo hacer:

>>> import foo 
>>> foo.bar() 
1 

Luego, en otra ventana, puedo cambiar foo.py a:

def bar(): 
    return "Hello" 

De vuelta en la sesión interactiva, llamando al foo.bar() sigue siendo las curvas 1, hasta que lo haga:

>>> reload(foo) 
<module 'foo' from 'foo.py'> 
>>> foo.bar() 
'Hello' 

Calling reload es uno manera de asegurar que su módulo es de hasta al día, incluso si el archivo en el disco ha cambiado. No es necesariamente el más eficiente (es mejor que verifique la última modificación en el archivo o use algo como pyinotify antes que reload), pero es ciertamente rápido de implementar.

Una de las razones por las que Python no lee desde el módulo de origen cada vez es que cargar un módulo es (relativamente) costoso, ¿qué pasaría si tuviera un módulo de 300kb y estuviera usando una sola constante del archivo? Python carga un módulo una vez y lo mantiene en la memoria, hasta que lo reload.

1

No estoy muy seguro de que sea eso lo que quieres decir, así que no dudes en corregirme. Está importando un módulo, vamos a llamarlo mymodule.py, en su programa, pero cuando cambia su contenido, ¿no ve la diferencia?

Python no buscará cambios en mymodule.py cada vez que se use, lo cargará por primera vez, lo compilará en bytecode y lo guardará internamente. Normalmente también guardará el bytecode compilado (mymodule.pyc). La próxima vez que inicie su programa, comprobará si mymodule.py es más reciente que mymodule.pyc y lo recompilará si es necesario.

Si es necesario, puede volver a cargar el módulo de forma explícita:

import mymodule 

[... some code ...] 

if userAskedForRefresh: 
    reload(mymodule) 

Por supuesto, es más complicado que eso y usted puede tener efectos secundarios dependiendo de lo que haga con su programa con respecto a la otra módulo, por ejemplo, si las variables dependen de las clases definidas en mymodule.

Como alternativa, puede utilizar la función execfile (o exec(), eval(), compile())

+0

Gracias a todos por sus respuestas. He intentado usar recargar y cerrar/volver a abrir el programa. El problema resultó ser causado por un archivo que se llamó igual, en el código original. Aunque pensé que lo estaba importando desde una nueva ubicación, todavía estaba usando el archivo anterior. – womble

3

que utiliza el siguiente al importar todos los objetos desde el interior de un módulo para asegurar web2py fue usar mi código actual:

import buttons 
import table 
reload(buttons) 
reload(table) 
from buttons import * 
from table import * 
0

que tenían el mismo problema exacto crear una secuencia de comandos de geoprocesamiento para ArcGIS 10.2. Tenía un script de caja de herramientas de python, un script de herramienta y luego un script común. Tengo un parámetro para Dev/Test/Prod en la herramienta que controlaría qué versión del código se ejecutó. Dev ejecutaría el código en la carpeta de desarrollo, la prueba de la carpeta de prueba y la prod desde la carpeta de prod. Los cambios en el script dev común no se ejecutarían cuando la herramienta se ejecutara desde ArcCatalog. Cerrando ArcCatalog no hizo diferencia. Aunque seleccioné Dev o Test, siempre se ejecutará desde la carpeta prod.

La adición de reload (myCommonModule) al script de la herramienta resolvió este problema.

3

Si se está ejecutando en un shell de IPython, existen algunos comandos mágicos que existen.

Los documentos IPython cubren esta función llamada autoreload extension.

Originalmente, encontré esta solución de Jonathan March's blog posting on this very subject (vea el punto 3 de ese enlace).

Básicamente todo lo que tiene que hacer es lo siguiente, y los cambios que realice se reflejan automáticamente después de guardar:

In [1]: %load_ext autoreload 

In [2]: %autoreload 2 

In [3]: Import MODULE 

In [4]: my_class = Module.class() 
     my_class.printham() 
Out[4]: ham 

In [5]: #make changes to printham and save 
In [6]: my_class.printham() 
Out[6]: hamlet