Comment puis-je enregistrer toutes les variables de la session Python actuelle?

93

Je souhaite enregistrer toutes les variables de mon environnement python actuel. Il semble qu'une option consiste à utiliser le module «pickle». Cependant, je ne veux pas faire cela pour 2 raisons:

1) Je dois appeler pickle.dump () pour chaque variable
2) Lorsque je veux récupérer les variables, je dois me souvenir de l'ordre dans lequel j'ai enregistré les variables, puis faire un pickle.load () pour récupérer chaque variable.

Je recherche une commande qui sauverait la session entière, de sorte que lorsque je charge cette session enregistrée, toutes mes variables soient restaurées. Est-ce possible?

Merci beaucoup!
Gaurav

Edit: Je suppose que cela ne me dérange pas d'appeler pickle.dump () pour chaque variable que je voudrais enregistrer, mais se souvenir de l'ordre exact dans lequel les variables ont été enregistrées semble être une grande restriction. Je veux éviter ça.

utilisateur10
la source

Réponses:

83

Si vous utilisez shelve , vous n'avez pas à vous souvenir de l'ordre dans lequel les objets sont décapés, car shelvevous donne un objet de type dictionnaire:

Pour mettre votre travail en rayon:

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

Restaurer:

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
la source
4
Parfait. C'est ce que je cherchais. BTW, je trouve cette phrase dans votre message super drôle: "Pour mettre votre travail de côté" :)
user10
3
Et là, j'ai trouvé que les "cornichons" étaient drôles! :) en.wikipedia.org/wiki/Inherently_funny_word
unutbu
1
Je sais que cette réponse est très ancienne lorsque je fais cela, j'ai l'erreur suivante: PicklingError: Can't pickle <built-in function raw_input>: it's not the same object as __builtin__.raw_inputje viens de déclarer 2 variables dans mon espace de travail. Des idées pour résoudre ce problème? Une meilleure façon de sauvegarder la session en cours est-elle sortie après cette réponse?
hellter le
1
J'ai le même problème concernant l'utilisation de shelve que décrit ci-dessus. PicklingError: Can't pickle <type 'numpy.int32'>: ce n'est pas le même objet que numpy.int32
Pu Zhang
1
Il semble que certaines fonctions et packages intégrés ne pourront pas être mis sur les tablettes, alors utilisez-les à la except:place de except TypeError:. Cela mettra de côté les variables définies par l'utilisateur et la plupart des objets (les trames de données pandas sont bien placées pour moi)
Nitro
64

Ayant été assis ici et n'ayant pas réussi à enregistrer le globals()sous forme de dictionnaire, j'ai découvert que vous pouvez décaper une session en utilisant la bibliothèque d'aneth.

Cela peut être fait en utilisant:

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

# and to load the session again:
dill.load_session(filename)
user2589273
la source
Je ne pense pas que l'aneth enregistre toutes les variables, par exemple si vous exécutez dill.dump_session () dans une fonction, les variables qui sont locales à cette fonction ne sont pas enregistrées.
Parsa
3
C'est juste un problème de portée, je suppose que vous pouvez simplement ajouter tous vos locaux () aux globals () si vous le devez?
user2589273
J'ai eu "TypeError: can't pickle Socket objects"
R. Cox
1
TypeError: no default __reduce__ due to non-trivial __cinit__
J'obtiens l'
J'ai essayé cela et j'ai trouvé qu'il ne pouvait pas enregistrer les tableaux nommés bien que cela puisse être une limitation de pickle.
rhody
6

Un moyen très simple qui pourrait satisfaire vos besoins. Pour moi, ça s'est plutôt bien passé:

Cliquez simplement sur cette icône dans l'explorateur de variables (côté droit de Spider):

Sauvegarde de toutes les variables au format * .spydata

Chargement de toutes les variables ou photos, etc.

shm2008
la source
J'ai enregistré hier toutes les variables au format .spydata et j'ai essayé d'importer des données aujourd'hui. Aucune variable n'est importée :(
Bharat Ram Ammu
Cela fonctionnait pour moi, mais maintenant que j'ai plus de données, plutôt que de créer un fichier Spydata, crée maintenant un fichier pickle avec zéro contenu ainsi que des centaines de fichiers npy. Comment puis-je les ouvrir s'il vous plaît?
R. Cox
4

Voici un moyen de sauvegarder les variables de l'espace de travail Spyder à l'aide des fonctions 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) 

Dites-moi si cela marche pour vous. David BH

David BH
la source
"NameError: le nom 'fpath' n'est pas défini": ai-je oublié quelque chose?
Thomas
C'est une bonne idée. Je pensais emprunter à l'espace de travail de Spyder pour la même chose. Mais je n'ai pas compris comment. Cependant, je n'ai pas bien compris votre code. Pourriez-vous s'il vous plaît dire, est-ce que cela fonctionne exactement comme Spyder qu'il capture automatiquement toutes les variables, ou je dois spécifier les variables que je souhaite utiliser?
cqcn1991
2

Ce que vous essayez de faire, c'est de mettre votre processus en veille prolongée. Cela a déjà été discuté . La conclusion est qu'il existe plusieurs problèmes difficiles à résoudre en essayant de le faire. Par exemple, avec la restauration des descripteurs de fichiers ouverts.

Il est préférable de penser au sous-système de sérialisation / désérialisation de votre programme. Ce n'est pas anodin dans de nombreux cas, mais c'est une bien meilleure solution dans une perspective à long terme.

Bien que si j'ai exagéré le problème. Vous pouvez essayer de décaper vos variables globales dict . Utilisez globals()pour accéder au dictionnaire. Comme il est indexé varname, vous n'avez pas à vous soucier de la commande.

nkrkv
la source
Non. Je n'essaye pas d'hiberner le processus. J'ai un shell python interactif sur lequel j'exécute plusieurs scripts et commandes. Je veux enregistrer la sortie (variables) de certaines de ces commandes, de sorte qu'à l'avenir, chaque fois que j'ai besoin d'accéder à la sortie, je puisse simplement lancer un shell python et charger toutes ces variables.
user10
Alors, pickle le dictionnaire var_name -> var_value
nkrkv
0

Si vous voulez que la réponse acceptée résumée fonctionne, vous pouvez utiliser:

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

pour obtenir / charger l'espace de travail:

import my_pkg as mp

x=1

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

print x #print 3 for me

cela a fonctionné quand je l'ai exécuté. J'admets que je ne comprends pas dir()et que je ne comprends pas à globals()100%, donc je ne suis pas sûr qu'il y ait une mise en garde étrange, mais jusqu'à présent, cela semble fonctionner. Les commentaires sont les bienvenus :)


après quelques recherches supplémentaires, si vous appelez save_workspacecomme je l'ai suggéré avec des globals et que vous êtes save_workspacedans une fonction, cela ne fonctionnera pas comme prévu si vous souhaitez enregistrer les veriables dans une portée locale. Pour cette utilisation locals(). Cela se produit parce que globals prend les globals du module où la fonction est définie, et non de l'endroit où elle est appelée, je suppose.

Pinocchio
la source
0

Vous pouvez l'enregistrer sous forme de fichier texte ou de fichier CVS. Les gens utilisent Spyder par exemple pour enregistrer des variables, mais il a un problème connu: pour des types de données spécifiques, il ne parvient pas à importer en cours de route.

Navid Farhoudi
la source