¿Cómo guardar todas las variables en la sesión actual de Python?

96

Quiero guardar todas las variables en mi entorno actual de Python. Parece que una opción es usar el módulo 'pickle'. Sin embargo, no quiero hacer esto por 2 razones:

  1. Tengo que llamar pickle.dump()para cada variable
  2. Cuando quiero recuperar las variables, debo recordar el orden en el que guardé las variables y luego hacer un pickle.load()para recuperar cada variable.

Estoy buscando algún comando que guarde toda la sesión, de modo que cuando cargue esta sesión guardada, todas mis variables se restauren. es posible?

Editar: Supongo que no me importa llamar pickle.dump()a cada variable que me gustaría guardar, pero recordar el orden exacto en el que se guardaron las variables parece una gran restricción. Quiero evitar eso.

usuario10
fuente

Respuestas:

84

Si usa shelve , no es necesario que recuerde el orden en el que se conservan los objetos, ya que shelvele da un objeto similar a un diccionario:

Para archivar su trabajo:

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()

Para restaurar:

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]
unutbu
fuente
4
Perfecto. Esto es lo que estaba buscando. Por cierto, encuentro esta oración en tu publicación súper divertida: "Para archivar tu trabajo" :)
usuario10
3
¡Y aquí pensé que los "encurtidos" eran divertidos! :) en.wikipedia.org/wiki/Inherently_funny_word
unutbu
1
Sé que esta respuesta es muy antigua, pero cuando hago esto, tengo el siguiente error: PicklingError: Can't pickle <built-in function raw_input>: it's not the same object as __builtin__.raw_inputsolo tengo 2 variables declaradas en mi espacio de trabajo. ¿Alguna idea sobre cómo solucionar esto? ¿Ha aparecido alguna forma mejor de guardar la sesión actual después de esta respuesta?
Hellter
1
Tengo el mismo problema con respecto al uso de la estantería como se describe anteriormente. PicklingError: No se puede encurtir <tipo 'numpy.int32'>: no es el mismo objeto que numpy.int32
Pu Zhang
1
Parece que algunas funciones y paquetes incorporados no se podrán archivar, así que utilice en except:lugar de except TypeError:. Esto archivará las variables definidas por el usuario y la mayoría de los objetos (los marcos de datos de pandas se archivaron bien para mí)
Nitro
65

Habiéndome sentado aquí y sin poder guardar el globals()como un diccionario, descubrí que puedes elegir una sesión usando la biblioteca de eneldo.

Esto se puede hacer usando:

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

# and to load the session again:
dill.load_session(filename)
usuario2589273
fuente
No creo que dill guarde todas las variables, por ejemplo, si ejecuta dill.dump_session () en una función, las variables que son locales para esa función no se guardan.
Parsa
3
Eso es solo un problema de alcance, supongo que podría agregar todos sus locales () a globales () si es necesario.
user2589273
Recibí "TypeError: no se pueden encurtir objetos de Socket"
R. Cox
1
Recibo el siguiente error de tipo al descargar la sesión: TypeError: no default __reduce__ due to non-trivial __cinit__
Kareem Jeiroudi
Intenté esto y descubrí que no puede guardar matrices con nombre, aunque esto podría ser una limitación de enmiendas.
rhody
6

Una forma muy sencilla que podría satisfacer sus necesidades. Para mí, funcionó bastante bien:

Simplemente, haga clic en este icono en el Explorador de variables (lado derecho de Spider):

Guardar todas las variables en formato * .spydata

Cargando todas las variables o fotos, etc.

shm2008
fuente
Ayer guardé todas las variables en formato .spydata e intenté importar datos hoy. No se importa ninguna variable :(
Bharat Ram Ammu
Esto funcionó para mí, pero ahora que tengo más datos, en lugar de hacer un archivo Spydata, ahora crea un archivo pickle con contenido cero, así como cientos de archivos npy. ¿Cómo abro estos por favor?
R. Cox
4

Aquí hay una forma de guardar las variables del espacio de trabajo de Spyder usando las funciones de 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) 

Déjame saber si te funciona. David BH

David BH
fuente
"NameError: el nombre 'fpath' no está definido": ¿olvidé algo?
Thomas
Es una buena idea. Estaba pensando en pedir prestado del espacio de trabajo de Spyder para lo mismo. Pero no descubrí cómo. Sin embargo, no entendí bien tu código. ¿Podría decirme si esto funciona exactamente como Spyder que detecta automáticamente todas las variables, o tengo que especificar las variables que quiero usar?
cqcn1991
2

Lo que está intentando hacer es hibernar su proceso. Esto ya se discutió . La conclusión es que existen varios problemas difíciles de resolver al intentar hacerlo. Por ejemplo, con la restauración de descriptores de archivos abiertos.

Es mejor pensar en el subsistema de serialización / deserialización de su programa. No es trivial en muchos casos, pero es una solución mucho mejor en una perspectiva a largo plazo.

Aunque si he exagerado el problema. Puede intentar encurtir su dict de variables globales . Úselo globals()para acceder al diccionario. Dado que está indexado por varname, no debe preocuparse por el pedido.

nkrkv
fuente
Nopes. No estoy intentando hibernar el proceso. Tengo un shell de Python interactivo en el que ejecuto varios scripts y comandos. Quiero guardar la salida (variables) de algunos de estos comandos, para que en el futuro, cuando necesite acceder a la salida, pueda simplemente iniciar un shell de Python y cargar todas estas variables.
usuario10
Por lo tanto, seleccione el diccionario var_name -> var_value
nkrkv
0

Si desea que la respuesta aceptada se resuma para que funcione, puede usar:

    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())

para obtener / cargar el espacio de trabajo:

import my_pkg as mp

x=1

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

print x #print 3 for me

funcionó cuando lo ejecuté. Admitiré que no entiendo dir()y al globals()100%, así que no estoy seguro de si podría haber alguna advertencia extraña, pero hasta ahora parece funcionar. Los comentarios son bienvenidos :)


después de investigar un poco más, si llama save_workspacecomo sugerí con globales y save_workspaceestá dentro de una función, no funcionará como se esperaba si desea guardar los verificables en un ámbito local. Para ese uso locals(). Esto sucede porque globals toma los globales del módulo donde se define la función, no desde donde se llama, supongo.

Pinocho
fuente
0

Puede guardarlo como un archivo de texto o un archivo CVS. La gente usa Spyder, por ejemplo, para guardar variables, pero tiene un problema conocido: para tipos de datos específicos, no se puede importar en el camino.

Navid Farhoudi
fuente