2010-06-02 3 views
49

Voglio salvare tutte le variabili nel mio attuale ambiente Python. Sembra che un'opzione sia usare il modulo "pickle". Tuttavia, non voglio fare questo per 2 motivi:Come posso salvare tutte le variabili nella sessione Python corrente?

1) Devo chiamare pickle.dump() per ogni variabile
2) Quando voglio recuperare le variabili, devo ricordare l'ordine in che ho salvato le variabili, quindi faccio un pickle.load() per recuperare ciascuna variabile.

Sto cercando un comando che salverà l'intera sessione, in modo che quando carico questa sessione salvata, tutte le mie variabili vengano ripristinate. È possibile?

Grazie mille!
Gaurav

Edit: Credo che non mi dispiace chiamare pickle.dump() per ogni variabile che vorrei salvare, ma ricordando l'ordine esatto in cui sono stati salvati i variabili sembra una grande limitazione. Voglio evitarlo.

risposta

53

Se si utilizza shelve, non c'è bisogno di ricordare l'ordine in cui vengono serializzate gli oggetti, dal momento shelve ti dà un dizionario-come oggetto:

di accantonare il proprio lavoro:

import shelve 

T='Hiya' 
val=[1,2,3] 

filename='/tmp/shelve.out' 
my_shelf = shelve.open(filename,'n') # 'n' for new 

for key in dir(): 
    try: 
     my_shelf[key] = globals()[key] 
    except TypeError: 
     # 
     # __builtins__, my_shelf, and imported modules can not be shelved. 
     # 
     print('ERROR shelving: {0}'.format(key)) 
my_shelf.close() 

per ripristinare:

my_shelf = shelve.open(filename) 
for key in my_shelf: 
    globals()[key]=my_shelf[key] 
my_shelf.close() 

print(T) 
# Hiya 
print(val) 
# [1, 2, 3] 
+1

Perfetto. Questo è quello che stavo cercando. A proposito, trovo questa frase nel tuo post super divertente: "Per accantonare il tuo lavoro" :) – user10

+0

E qui pensavo che "sottaceti" fossero divertenti! :) http://en.wikipedia.org/wiki/Inherently_funny_word – unutbu

+0

è possibile astrarre i dettagli del salvataggio delle variabili in una funzione separata? Ad esempio, quando si esegue il loop dei nomi nello spazio dei nomi locali corrente, è possibile passarlo come argomento, ma come passare le globali? Devi anche passare le globali? come in 'save (dir(), globals())' e quindi esegui il tuo codice sopra? Inoltre è possibile chiamare semplicemente una funzione che riassume il ripristino? – Pinocchio

2

Quello che stai cercando di fare è di ibernare il tuo processo. Questo era già discussed. La conclusione è che esistono diversi problemi difficili da risolvere durante il tentativo di farlo. Ad esempio con il ripristino dei descrittori di file aperti.

È meglio pensare al sottosistema di serializzazione/deserializzazione per il proprio programma. In molti casi non è banale, ma è una soluzione di gran lunga migliore in una prospettiva di lungo periodo.

Anche se ho esagerato il problema. Puoi provare a sottaceti le tue variabili globali dict. Utilizzare globals() per accedere al dizionario. Dato che è indicizzato da un varname, non devi preoccuparti per l'ordine.

+0

Nopes. Non sto cercando di ibernare il processo. Ho una shell python interattiva su cui eseguo diversi script e comandi. Voglio salvare l'output (variabili) di alcuni di questi comandi, in modo che in futuro ogni volta che ho bisogno di accedere all'output, posso semplicemente attivare una shell python e caricare tutte queste variabili. – user10

+0

Quindi, decolla il dizionario var_name -> var_value – nkrkv

+0

Grazie per la risposta! – user10

3

Ecco un modo salvare le variabili dello spazio di lavoro Spyder utilizzando le funzioni spyderlib

#%% Load data from .spydata file 
from spyderlib.utils.iofuncs import load_dictionary 

globals().update(load_dictionary(fpath)[0]) 
data = load_dictionary(fpath) 



#%% Save data to .spydata file 
from spyderlib.utils.iofuncs import save_dictionary 
def variablesfilter(d): 
    from spyderlib.widgets.dicteditorutils import globalsfilter 
    from spyderlib.plugins.variableexplorer import VariableExplorer 
    from spyderlib.baseconfig import get_conf_path, get_supported_types 

    data = globals() 
    settings = VariableExplorer.get_settings() 

    get_supported_types() 
    data = globalsfilter(data,     
         check_all=True, 
         filters=tuple(get_supported_types()['picklable']), 
         exclude_private=settings['exclude_private'], 
         exclude_uppercase=settings['exclude_uppercase'], 
         exclude_capitalized=settings['exclude_capitalized'], 
         exclude_unsupported=settings['exclude_unsupported'], 
         excluded_names=settings['excluded_names']+['settings','In']) 
    return data 

def saveglobals(filename): 
    data = globalsfiltered() 
    save_dictionary(data,filename) 


#%% 

savepath = 'test.spydata' 

saveglobals(savepath) 

Fammi sapere se funziona per voi. David B-H

+0

"NameError: name 'fpath' non è definito": ho dimenticato qualcosa? – Thomas

+0

Questa è una buona idea. Stavo pensando di prendere in prestito dallo spazio di lavoro di Spyder per la stessa cosa. Ma non ho capito come. Tuttavia, non ho capito bene il tuo codice. Potresti dirlo, funziona esattamente come Spyder che cattura automaticamente tutte le varibles o devo specificare le variabili che voglio usare? – cqcn1991

25

Avere seduto qui e non è riuscito a salvare la globals() come un dizionario, ho scoperto è possibile salamoia una sessione utilizzando la libreria aneto.

questo può essere fatto utilizzando:

import dill       #pip install dill --user 
filename = 'globalsave.pkl' 
dill.dump_session(filename) 

# and to load the session again: 
dill.load_session(filename) 
+1

Penso che questo sia il modo più semplice, grazie :) – Mohammad

+0

Non penso che dill salvi tutte le variabili, ad esempio se si esegue dill.dump_session() in una funzione le variabili che sono locali a quella funzione non vengono salvate. – par

+0

Questo è solo un problema di ambito, suppongo che potresti semplicemente aggiungere tutti i tuoi locals() ai globals() se è necessario? – user2589273

0

Se si desidera che la risposta accettata astratta di funzionare è possibile utilizzare:

import shelve 

    def save_workspace(filename, names_of_spaces_to_save, dict_of_values_to_save): 
    ''' 
     filename = location to save workspace. 
     names_of_spaces_to_save = use dir() from parent to save all variables in previous scope. 
      -dir() = return the list of names in the current local scope 
     dict_of_values_to_save = use globals() or locals() to save all variables. 
      -globals() = Return a dictionary representing the current global symbol table. 
      This is always the dictionary of the current module (inside a function or method, 
      this is the module where it is defined, not the module from which it is called). 
      -locals() = Update and return a dictionary representing the current local symbol table. 
      Free variables are returned by locals() when it is called in function blocks, but not in class blocks. 

     Example of globals and dir(): 
      >>> x = 3 #note variable value and name bellow 
      >>> globals() 
      {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'x': 3, '__doc__': None, '__package__': None} 
      >>> dir() 
      ['__builtins__', '__doc__', '__name__', '__package__', 'x'] 
    ''' 
    print 'save_workspace' 
    print 'C_hat_bests' in names_of_spaces_to_save 
    print dict_of_values_to_save 
    my_shelf = shelve.open(filename,'n') # 'n' for new 
    for key in names_of_spaces_to_save: 
     try: 
      my_shelf[key] = dict_of_values_to_save[key] 
     except TypeError: 
      # 
      # __builtins__, my_shelf, and imported modules can not be shelved. 
      # 
      #print('ERROR shelving: {0}'.format(key)) 
      pass 
    my_shelf.close() 

    def load_workspace(filename, parent_globals): 
     ''' 
      filename = location to load workspace. 
      parent_globals use globals() to load the workspace saved in filename to current scope. 
     ''' 
     my_shelf = shelve.open(filename) 
     for key in my_shelf: 
      parent_globals[key]=my_shelf[key] 
     my_shelf.close() 

an example script of using this: 
import my_pkg as mp 

x = 3 

mp.save_workspace('a', dir(), globals()) 

per ottenere/caricare l'area di lavoro:

import my_pkg as mp 

x=1 

mp.load_workspace('a', globals()) 

print x #print 3 for me 

ha funzionato quando l'ho eseguito. Devo ammettere che non capisco dir() e globals() 100%, quindi non sono sicuro se ci potrebbe essere qualche strana avvertenza, ma finora sembra funzionare. I commenti sono benvenuti :)


dopo qualche ricerca più se si chiama save_workspace come ho suggerito con globali e save_workspace è all'interno di una funzione non funzionerà come previsto se si desidera salvare i veriables in un ambito locale. Per quello usa locals(). Ciò accade perché globals prende i globali dal modulo in cui è definita la funzione, non da dove viene chiamata sarebbe la mia ipotesi.

-1

Volevo aggiungere un commento alla risposta di unutbu, ma non ho ancora abbastanza reputazione. Ho anche avuto il problema con

PicklingError: Can't pickle <built-in function raw_input>: it's not the same object as __builtin__.raw_input 

ho aggirato con l'aggiunta di una regola per passare tutte le eccezioni e dimmi che cosa non ha fatto negozio. unubtu sta tweaked codice, per comodità copypaste:

di accantonare il proprio lavoro:

import shelve 

filename='/tmp/shelve.out' 
my_shelf = shelve.open(filename,'n') # 'n' for new 

for key in dir(): 
    try: 
     my_shelf[key] = globals()[key] 
    except TypeError: 
     # 
     # __builtins__, my_shelf, and imported modules can not be shelved. 
     # 
     print('TypeError shelving: {0}'.format(key)) 
    except: 
     # catches everything else 
     print('Generic error shelving: {0}'.format(key)) 
my_shelf.close() 

ripristinare:

my_shelf = shelve.open(filename) 
for key in my_shelf: 
    globals()[key]=my_shelf[key] 
my_shelf.close()