Come posso salvare tutte le variabili nella sessione corrente di Python?


93

Voglio salvare tutte le variabili nel mio attuale ambiente Python. Sembra che un'opzione sia usare il modulo "pickle". Tuttavia, non voglio farlo per 2 motivi:

1) Devo chiamare pickle.dump () per ogni variabile
2) Quando voglio recuperare le variabili, devo ricordare l'ordine in cui ho salvato le variabili, e poi fare un pickle.load () per recuperare ogni variabile.

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

Molte grazie!
Gaurav

Modifica: immagino che non mi dispiaccia chiamare pickle.dump () per ogni variabile che vorrei salvare, ma ricordare l'ordine esatto in cui le variabili sono state salvate sembra una grande restrizione. Voglio evitarlo.

Risposte:


83

Se usi shelve , non devi ricordare l'ordine in cui gli oggetti vengono decapati, poiché shelveti dà un oggetto simile a un dizionario:

Per accantonare il tuo 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()

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]

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

3
E qui ho pensato che i "sottaceti" fossero divertenti! :) en.wikipedia.org/wiki/Inherently_funny_word
unutbu

1
So che questa risposta è molto vecchia perché quando lo faccio ho il seguente errore: PicklingError: Can't pickle <built-in function raw_input>: it's not the same object as __builtin__.raw_inputho solo 2 variabili dichiarate nel mio spazio di lavoro. Qualche idea su come risolvere questo problema? Dopo questa risposta è uscito un modo migliore per salvare la sessione corrente?
Hellter

1
Ho lo stesso problema per quanto riguarda l'utilizzo di shelve come descritto sopra. PicklingError: Can't pickle <type 'numpy.int32'>: non è lo stesso oggetto di numpy.int32
Pu Zhang

1
Sembra che alcune funzioni e pacchetti incorporati non possano essere accantonati, quindi usa al except:posto di except TypeError:. Ciò accantonerà le variabili definite dall'utente e la maggior parte degli oggetti (i frame di dati dei panda sono stati accantonati bene per me)
Nitro

64

Dopo globals()essermi seduto qui e non aver salvato il come dizionario, ho scoperto che puoi mettere sott'acqua una sessione usando la libreria di aneto.

Questo può essere fatto usando:

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

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

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

3
Questo è solo un problema di ambito, immagino che potresti semplicemente aggiungere tutti i tuoi locali () a globali () se devi?
user2589273

Ho ricevuto "TypeError: can't pickle Socket objects"
R. Cox

1
Ottengo il seguente errore di tipo durante il dumping della sessione: TypeError: no default __reduce__ due to non-trivial __cinit__
Kareem Jeiroudi

Ho provato questo e ho scoperto che non è possibile salvare array denominati anche se questa potrebbe essere una limitazione di sottaceti.
Rhody

6

Un modo molto semplice che potrebbe soddisfare le tue esigenze. Per me è andata abbastanza bene:

Basta fare clic su questa icona in Esplora variabili (lato destro di Spider):

Salvataggio di tutte le variabili in formato * .spydata

Caricamento di tutte le variabili o foto ecc.


Ieri ho salvato tutte le variabili in formato .spydata e oggi ho provato a importare i dati. Nessuna variabile viene importata :(
Bharat Ram Ammu

Questo funzionava per me, ma ora che ho più dati, invece di creare un file Spydata, ora crea un file pickle con zero contenuti e centinaia di file npy. Come li apro per favore?
R. Cox,

4

Ecco un modo per salvare le variabili dell'area di lavoro di Spyder utilizzando le funzioni di 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 te. David BH


"NameError: il nome 'fpath' non è definito": ho dimenticato qualcosa?
Thomas

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 per favore dire, funziona esattamente come Spyder che cattura automaticamente tutte le variabili, o devo specificare le variabili che voglio usare?
cqcn1991

2

Quello che stai cercando di fare è ibernare il tuo processo. Questo è stato discusso già . La conclusione è che esistono diversi problemi difficili da risolvere mentre si cerca di farlo. Ad esempio con il ripristino dei descrittori di file aperti.

È meglio pensare al sottosistema di serializzazione / deserializzazione per il tuo programma. Non è banale in molti casi, ma è una soluzione di gran lunga migliore in una prospettiva a lungo termine.

Anche se ho esagerato il problema. Puoi provare a mettere sottaceto il tuo dict delle variabili globali . Utilizzare globals()per accedere al dizionario. Poiché è indicizzato in base al nome, non devi preoccuparti dell'ordine.


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 avrò bisogno di accedere all'output, potrò semplicemente avviare una shell python e caricare tutte queste variabili.
user10

Quindi, seleziona il dizionario nome_var -> valore_var
nkrkv

0

Se vuoi che la risposta accettata astratta funzioni, puoi usare:

    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 al globals()100% quindi non sono sicuro che ci possa essere qualche strano avvertimento, ma finora sembra funzionare. I commenti sono benvenuti :)


dopo qualche ricerca in più se chiami save_workspacecome ho suggerito con globals ed save_workspaceè all'interno di una funzione, non funzionerà come previsto se vuoi salvare i verificabili in un ambito locale. Per quell'uso locals(). Ciò accade perché globals prende le globali dal modulo in cui è definita la funzione, non da dove è chiamata sarebbe la mia ipotesi.


0

Puoi salvarlo come file di testo o file CVS. Le persone usano Spyder ad esempio per salvare le variabili, ma ha un problema noto: per tipi di dati specifici non riesce a importare lungo la strada.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.