Como posso salvar todas as variáveis ​​na sessão Python atual?

93

Eu quero salvar todas as variáveis ​​em meu ambiente Python atual. Parece que uma opção é usar o módulo 'pickle'. No entanto, não quero fazer isso por 2 motivos:

1) Tenho que chamar pickle.dump () para cada variável
2) Quando eu quiser recuperar as variáveis, devo lembrar a ordem em que salvei as variáveis ​​e, em seguida, fazer pickle.load () para recuperar cada variável.

Estou procurando algum comando que salvaria toda a sessão, para que quando eu carregar esta sessão salva, todas as minhas variáveis ​​sejam restauradas. Isso é possível?

Muito obrigado!
Gaurav

Edit: Acho que não me importo de chamar pickle.dump () para cada variável que gostaria de salvar, mas lembrar a ordem exata em que as variáveis ​​foram salvas parece uma grande restrição. Eu quero evitar isso.

usuário 10
fonte

Respostas:

83

Se você usar shelve , não é necessário lembrar a ordem em que os objetos são conservados, pois shelveoferece um objeto semelhante a um dicionário:

Para arquivar seu trabalho:

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

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
fonte
4
Perfeito. Isso é o que eu estava procurando. BTW, acho esta frase super engraçada no seu post: "Para arquivar seu trabalho" :)
user10
3
E aqui eu achei "picles" engraçados! :) en.wikipedia.org/wiki/Inherently_funny_word
unutbu
1
Eu sei que esta resposta é muito antiga, mas quando faço isso, tenho o seguinte erro: PicklingError: Can't pickle <built-in function raw_input>: it's not the same object as __builtin__.raw_inputAcabo de ter 2 variáveis ​​declaradas em meu espaço de trabalho. Todas as ideias sobre como resolver isso? Após esta resposta, surgiu alguma maneira melhor de salvar a sessão atual?
hellter
1
Tenho o mesmo problema com relação ao uso de prateleiras conforme descrito acima. PicklingError: Não é possível conservar <type 'numpy.int32'>: não é o mesmo objeto que numpy.int32
Pu Zhang
1
Parece que algumas funções e pacotes embutidos não poderão ser arquivados, então apenas use em except:vez de except TypeError:. Isso arquivará as variáveis ​​definidas pelo usuário e a maioria dos objetos (quadros de dados do pandas arquivados bem para mim)
Nitro
64

Tendo sentado aqui e falhado em salvar o globals()como um dicionário, descobri que você pode selecionar uma sessão usando a biblioteca de endro.

Isso pode ser feito usando:

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

# and to load the session again:
dill.load_session(filename)
user2589273
fonte
Eu não acho que o dill salva todas as variáveis, por exemplo, se você executar dill.dump_session () em uma função, as variáveis ​​locais para essa função não são salvas.
Parsa
3
Isso é apenas um problema de escopo, eu acho que você poderia apenas anexar todos os seus locais () a globals () se necessário.
user2589273
Recebi "TypeError: não é possível conservar objetos Socket"
R. Cox
1
Recebo o seguinte erro de tipo ao TypeError: no default __reduce__ due to non-trivial __cinit__
encerrar
Tentei fazer isso e descobri que não é possível salvar matrizes nomeadas, embora isso possa ser uma limitação de pickle.
Rhody
6

Uma maneira muito fácil de satisfazer suas necessidades. Para mim, funcionou muito bem:

Basta clicar neste ícone no Explorador de variáveis ​​(lado direito do Spider):

Salvando todas as variáveis ​​no formato * .spydata

Carregando todas as variáveis ​​ou fotos etc.

shm2008
fonte
Salvei todas as variáveis ​​no formato .spydata ontem e tentei importar os dados hoje. Nenhuma variável é importada :(
Bharat Ram Ammu
Isso estava funcionando para mim, mas agora que tenho mais dados, em vez de fazer um arquivo Spydata, agora cria um arquivo pickle com conteúdo zero, bem como centenas de arquivos npy. Como faço para abrir isso, por favor?
R. Cox
4

Aqui está uma maneira de salvar as variáveis ​​do espaço de trabalho do Spyder usando as funções do 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) 

Deixe-me saber se funciona para você. David BH

David BH
fonte
"NameError: o nome 'fpath' não está definido": esqueci-me de algo?
Thomas
Essa é uma boa ideia. Eu estava pensando em pegar emprestado do espaço de trabalho do spyder para a mesma coisa. Mas não descobri como. No entanto, não entendi muito bem o seu código. Você poderia dizer se isso funciona exatamente como o Spyder que captura automaticamente todas as variáveis, ou eu tenho que especificar as variáveis ​​que desejo usar?
cqcn1991
2

O que você está tentando fazer é hibernar o processo. Isso já foi discutido . A conclusão é que existem vários problemas difíceis de resolver ao tentar fazê-lo. Por exemplo, com a restauração de descritores de arquivos abertos.

É melhor pensar sobre o subsistema de serialização / desserialização para seu programa. Não é trivial em muitos casos, mas é uma solução muito melhor em uma perspectiva de longo prazo.

Embora eu tenha exagerado o problema. Você pode tentar conservar seu dict de variáveis ​​globais . Use globals()para acessar o dicionário. Uma vez que é indexado por varname, você não precisa se preocupar com o pedido.

nkrkv
fonte
Não. Não estou tentando hibernar o processo. Eu tenho um shell Python interativo no qual executo vários scripts e comandos. Quero salvar a saída (variáveis) de alguns desses comandos, para que, no futuro, sempre que eu precisar acessar a saída, eu possa simplesmente iniciar um shell Python e carregar todas essas variáveis.
usuário
Então, escolha o dicionário var_name -> var_value
nkrkv
0

Se quiser que a resposta aceita resumida funcione, você pode 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 obter / carregar o espaço de trabalho:

import my_pkg as mp

x=1

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

print x #print 3 for me

funcionou quando o executei. Admito que não entendo dir()e globals()100%, então não tenho certeza se pode haver alguma advertência estranha, mas até agora parece funcionar. Comentários são bem-vindos :)


depois de mais pesquisas se você chamar save_workspacecomo sugeri com globais e save_workspaceestiver dentro de uma função, ela não funcionará como esperado se você quiser salvar os verificáveis ​​em um escopo local. Para esse uso locals(). Isso acontece porque os globais pegam os globais do módulo onde a função é definida, não de onde ela é chamada, seria o meu palpite.

Pinóquio
fonte
0

Você pode salvá-lo como um arquivo de texto ou um arquivo CVS. As pessoas usam o Spyder, por exemplo, para salvar variáveis, mas ele tem um problema conhecido: para tipos de dados específicos, ele não consegue importar na estrada.

Navid Farhoudi
fonte