2016-01-29 11 views

risposta

3

Obsolescenza nota: questo è stato scritto per IPython 4.0.1. As of v5, IPython no longer uses readline.


Nessun modo di magazzino, può essere aggiunto o lavorato in giro.

Ci sono due tipi di storia in IPython:

  • readline storia. È disponibile con tasti speciali/combinazioni di tasti (su/giù, Ctrl-R ecc.). Memorizza solo le righe immesse (con <Enter>) sulla console (o, in pyreadline, incollate dagli Appunti). IPython si basa su un'implementazione locale di Python readline API che non ha una funzione "non aggiungere" e normalmente aggiunge ogni riga alla cronologia.
    IPython ha una funzione per alleviare questo, IPython.core.interactiveshell.ReadlineNoRecord, un gestore di contesto che crea un'istantanea della cronologia, quindi lo ripristina. A partire da ipython 4.0.1, è utilizzato solo dalla magia %run per evitare di aggiungere input interattivi di script alla cronologia.

  • Cronologia IPython. È salvato nel DB e nelle variabili automatiche. Contiene ingressi completi (readline afferra ogni <Enter> "riga edita separatamente per quelli multilinea) e le uscite. Il salvataggio è implementato in HistoryManager.store_inputs() (per gli ingressi) e HistoryManager.store_output() (per le uscite) che viene chiamato da InteractiveShell.run_cell ed è governato dall'argomento store_history. Quest'ultimo è a sua volta chiamato da TerminalInteractiveShell.interact con store_history=True.

Ci sono due modi per risolvere il problema per uno strato:

  • evitano la aggiungendo l'ingresso in primo luogo. Questo non può essere fatto con una magia preceduta da un comando, solo con una che viene eseguita come comando separato e commuta una bandiera. Questo perché, come hai visto, l'input corrente è già stato memorizzato nel momento in cui un comando magico ottiene il controllo.

    • readline: non c'è alcuna voce pertinente nell'API pubblica, quindi è specifica dell'implementazione. Per esempio. per pyreadline, l'aggiunta viene eseguita con pyreadline.modes.basemode.BaseMode.add_history(). L'oggetto modalità è accessibile come get_ipython().readline.rl.mode.
    • Decorazione run_cell e add_history con i wrapper che controllano i flag negli oggetti corrispondenti e uno custom magic command che imposta/alternarli dovrebbero fare il trucco.
  • rimuovere automaticamente prove input/output dalla cronologia immediatamente dopo l'esecuzione. Questo può essere fatto con un prefisso magico.

    • IPython: HistoryManager non ha alcuna possibilità di rimuovere voci (né da DB né da variabili). Ahimè, l'hacking del DB a mano/sostituzione del magazzino HistoryManager è necessario. Si noti inoltre che la classe ha una cache opzionale di HistoryManager.db_cache_size (disabilitata per impostazione predefinita).
    • readline: remove_history_item(index) è nell'API. È necessario conoscere il numero di righe nell'input.

In alternativa, se si richiedono solo questo per immettere le password, prendere in considerazione altri modi che non richiamano la password sullo schermo (quindi non lo rende una parte della storia della console):

  • getpass.getpass()
  • riporlo altrove (come un file di configurazione solo leggibile da te)
+0

1. _ "Impedisci di aggiungere l'input in primo luogo. Questo non può essere fatto con una magia preceduta da un comando, solo con una che viene eseguita come comando separato e commuta un flag" _ che cos'è un esempio di comando separato commutare un flag per impedire l'aggiunta dell'input? 2. _Decorando run_cell e add_history con i wrapper che controllano i flag negli oggetti corrispondenti e un comando magico personalizzato che li imposta/li commuta dovrebbe fare il trucco._ Puoi aggiungere un esempio? – ShreevatsaR

+0

@ShreevatsaR 0) vedi nota sull'obsolescenza; 1) '% toggle',' your_command', '% toggle'; 2) questo significa sostituire quelle funzioni con i wrapper attorno a loro; un esempio va oltre lo scopo della risposta, questo dovrebbe essere chiaro a chiunque abbia una discreta esperienza. –

4

Penso di averlo finalmente capito. Questo metodo non impedisce realmente a ipython di registrare la cronologia ma in realtà lo elimina il record della cronologia. Ma penso che sia ancora un buon modo per raggiungere questo obiettivo.

La cronologia di ipython è memorizzata in un file sqlite database$(ipython locate)/profile_default/history.sqlite.

La tabella del database Storia ha quattro colonne: sessione, linea, fonte e source_raw. La colonna sessione presenta per il session_id della sessione corrente, può essere ottenuta con il metodo in ipython: get_ipython().history_manager.hisdb.get_last_session_id() in ipython. La colonna riga è solo la riga num.

Così che cosa ho intenzione di fare è ho intenzione di eliminare questo record nel database tra ipython ambiente:

1) L'oggetto storia db può essere ottenere usando get_ipython().history_manager.db in ipython

hismgr = get_ipython().history_manager 

2) ottenere l'id di sessione:

session_id = hismgr.get_last_session_id() 

3) eliminare il suo linea torio con il line_id (assumere è 111 qui) e session_id

hismgr.db.execute('DELETE FROM history WHERE line={0} and session={1}'.format(111, session_id)) 

4) elenco In e Out Array è inoltre genere come storia, ma memorizzato nella memoria, in modo che possa essere spazzare o riscrittura come variabile .

In[111]=Out[111]='' 

Per 'evitare che un comando di essere salvata ipython storia', significa cancellare la storia primato della linea nel database e e riscrivere In e Out Array in ambiente ipython. E potremmo combinare queste quattro linee in una sola per fare il lavoro una volta per tutte. Ecco un esempio se vogliamo eliminare la linea 128:

In [127]: history -l 3 -n 
124: history -l 3 -n 
125: hismgr = get_ipython().history_manager; session_id = hismgr.get_last_session_id();hismgr.db.execute('DELETE FROM history WHERE line={0} and session={1}'.format(123, session_id)) 
126: history -l 3 -n 

In [128]: passwd='123456' 

In [129]: hismgr = get_ipython().history_manager; session_id = hismgr.get_last_session_id();hismgr.db.execute('DELETE FROM history WHERE line={0} and session={1}'.format(128, session_id));In[128]=Out[128]=''; 
Out[129]: <sqlite3.Cursor at 0x7f8dce3dae30> 

In [130]: history -l 3 -n 
126: history -l 3 -n 
127: history -l 3 -n 
129: hismgr = get_ipython().history_manager; session_id = hismgr.get_last_session_id();hismgr.db.execute('DELETE FROM history WHERE line={0} and session={1}'.format(128, session_id));In[128]=Out[128]=''; 

La linea di storia 128 è andato.

Ecco alcuni documenti che ho attraversato

IPython.core.history.HistoryManager

python-sqlite3

+0

Questo in realtà non "evita di memorizzare una riga nella cronologia", piuttosto lo cancella dalla cronologia post factum. –

+0

@ivan_pozdeev Lo so. Ma ho letto il documento ipython, e non riesco a trovare un modo per "davvero impedire un comando salvato nella cronologia", quindi vengo fuori che se cancello la linea farei lo stesso lavoro. – realhu

Problemi correlati