2015-08-28 10 views
5

Quando si tenta un modulo autodidatta, è probabile che finisca con errori nelle prime volte.Come faccio a rendere ipython consapevole delle modifiche apportate a un modulo auto-scritto?

Ma quando si corregge questi errori, ipython sembra non accorgersene.

Esiste un comando ipython per ricaricare il nuovo modulo? 'chiaro' non fa il trucco. Finora, l'unica cosa che funziona è "uscire" e iniziare una nuova sessione. Ma questo significa anche rifare tutto quello che ho fatto finora.

Oppure devo aggiungere qualcosa al modulo che uccide tutte le sue variabili interne dopo che è stato eseguito?

Esempio:

from mymodule import readCSVts 
import pandas as pd 
data = readCSVts('file.csv') 

TypeError         Traceback (most recent call last) 
<ipython-input-158-8f82f1a78260> in <module>() 
----> 1 data = readCSVts('file.csv') 

/home/me/path/to/mymodule.py in readCSVts(filename) 
    194     Cons_NaNs=hydroTS[(hydroTS.level.isnull())&(hydroTS.level.shift().isnull())&(hydroTS.level.shift(periods=2).isnull())] 
    195     #This is a pandas dataframe containing all rows with NaN 
    196     Cons_NaNs_count = len(Cons_NaNs) 
    197     Cons_NaNs_str = str(Cons_NaNs_count) 
    198     Cons_NaN_Name_joiner = [current_csv,';',Cons_NaNs] 
--> 199     Cons_NaN_Name_str = ''.join(Cons_NaN_Name_joiner) 

TypeError: sequence item 2: expected string, DataFrame found 

OK, che è facile. Ho fatto un errore di battitura nella riga 198 e ho scritto Cons_NaNs anziché Cons_NaNs_str, e quindi ottengo l'ovvio errore di provare ad unire un dataframe con una stringa.

Ma dopo aver fissato nel file mymodule.py, ottengo il seguente (abbreviato) di errore:

197     Cons_NaNs_str = str(Cons_NaNs_count) 
    198     Cons_NaN_Name_joiner = [current_csv,';',Cons_NaNs_str] 
--> 199     Cons_NaN_Name_str = ''.join(Cons_NaN_Name_joiner) 

TypeError: sequence item 2: expected string, DataFrame found 

Guardando il traceback, ipython è ben consapevole dei cambiamenti è fatto nel file di origine, mostra che ho corretto l'errore con lo _str mancante, ma dà ancora un errore, che al primo sguardo sembra essere impossibile. Dopo aver eseguito clear e reimportato tutto, mostra lo stesso comportamento.

Quindi, per essere sicuro di non aver fatto uno stupido errore da qualche parte lungo il percorso, sono andato passo passo attraverso il mio intero modulo in ipython. E ogni variabile che mi porta a quel punto si comporta come previsto.

Cons_NaNs è un dataframe, Cons_NaNs_count è un numero intero e Cons_NaNs_str è una stringa.

Così ho chiuso ipython, lo ho riavviato e reimportato tutto e ora funziona.

Ma dover uscire da ipython fa schifo. Il più delle volte questo significa dover reimportare dozzine di cose e fare alcune dozzine di comandi, per arrivare al punto in cui posso testare su cosa sto lavorando attualmente.

+3

Hai provato ['reload'] (https://docs.python.org/2/library/functions.html#reload)? – jonrsharpe

risposta

2

Questo non è solo per ipython, ma Python in generale memorizza nella cache un modulo quando viene importato per la prima volta in sys.modules. Quindi, dopo la prima importazione, ogni volta che si tenta di importarlo, si otterrà l'oggetto modulo memorizzato nella cache da sys.modules.

Per fare in modo che Python ricarichi l'oggetto modulo senza dover riavviare Python, in modo che le modifiche apportate al modulo vengano riflesse, è necessario utilizzare reload() built-in function (Python 2.x) o importlib.reload() (Python 3.x).

Python 2.x -

<module> = reload(<module>) 

Esempio -

import module 
module = reload(module) #This requires the module as it is, not a string. 

Python 3.x -

import importlib 
<module> = importlib.reload(<module>) 

Simile a Python 2.x esempio di cui sopra, basta usare importlib.reload() invece di reload()

+0

Come si usa "ricarica" ​​in 2.x con un modulo selfmade? 'reload (mymodule)', 'reload ('mymodule.py')' e 'reload (readCSVts)' falliscono tutti con 'NameError: name 'mymodule' non è definito' o' TypeError: reload() argomento deve essere module' –

+0

do 'importa mymodule; ricarica (mymodule) '. –

+0

Inoltre, 'reload()' richiede l'oggetto modulo così com'è, non una stringa .. –

0

Quando si uccide il server IPython notebook e riavviarlo, si avrà una nuova istanza del kernel che non persistono con il notebook si. Si dovrebbe avviare il flusso di lavoro subito dopo aver aperto il notebook eseguendo tutte le celle. Nel menu in alto, selezionare "cellulo> Esegui tutti"

+0

Sto solo lavorando con ipython "normale". Nessun quaderno qui. –

4

C'è un modo specifico ipython, è possibile utilizzare istituiti autoreload:

In [1]: %load_ext autoreload 

In [2]: %autoreload 2 

In [3]: from foo import some_function 

In [4]: some_function() 
Out[4]: 42 

In [5]: # open foo.py in an editor and change some_function to return 43 

In [6]: some_function() 
Out[6]: 43 

Il modulo è stato ricaricato senza ricaricare esplicitamente, e la oggetto importato con da foo import ... è stato anche aggiornato.

Uso i seguenti comandi magici sono forniti:

%autoreload

Reload all modules (except those excluded by %aimport) automatically now.

%autoreload 0

Disable automatic reloading.

%autoreload 1

Reload all modules imported with %aimport every time before executing the >Python code typed.

%autoreload 2

Reload all modules (except those excluded by %aimport) every time before executing the Python code typed.

%aimport

List modules which are to be automatically imported or not to be imported.

%aimport foo

Import module ‘foo’ and mark it to be autoreloaded for %autoreload 1

%aimport -foo

Mark module ‘foo’ to not be autoreloaded.

C'è anche dreload che lavorerà per python2 e 3.

dreload(module) 
+0

Grazie, è molto utile! Ma per ora preferisco ricaricare a mano, se necessario. –

+1

@JC_CL, 'dreload' lo farà,' dreload (module) 'senza richiedere importazioni per python2 o 3 –

Problemi correlati