如何在当前python会话中保存所有变量?


93

我想将所有变量保存在当前的python环境中。似乎一种选择是使用“棘手”模块。但是,我不想这样做有两个原因:

1)我必须为每个变量调用pickle.dump()
2)当我想检索变量时,必须记住保存变量的顺序,然后执行pickle.load()来检索每个变量。

我正在寻找可以保存整个会话的命令,以便在加载此保存的会话时,将还原所有变量。这可能吗?

非常感谢!
高拉夫

编辑:我想我不介意为每个要保存的变量调用pickle.dump(),但是记住保存变量的确切顺序似乎是一个很大的限制。我想避免这种情况。

Answers:


83

如果使用shelve,则不必记住对象的腌制顺序,因为shelve它会为您提供类似于字典的对象:

搁置您的工作:

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

恢复:

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
完善。这就是我想要的。顺便说一句,我觉得这句话在您的帖子中超级有趣:“要搁置您的工作” :)
user10 2010年

3
在这里,我认为“挑剔”很有趣!:) en.wikipedia.org/wiki/Inherently_funny_word
unutbu 2010年

1
我知道这样做的答案很老,我遇到以下错误:PicklingError: Can't pickle <built-in function raw_input>: it's not the same object as __builtin__.raw_input我在工作区中声明了2个变量。关于如何解决这个问题的任何想法?在此答案之后,有什么更好的方法可以保存当前会话吗?
2013年

1
关于上述货架的使用,我有同样的问题。PicklingError:无法腌制<type'numpy.int32'>:它与numpy.int32不是同一对象
Pu Zhang

1
看起来有些内置函数和包无法搁置,因此请使用except:代替except TypeError:。这将搁置用户定义的变量和大多数对象(对我来说,熊猫数据框搁置得很好)
Nitro

64

坐在这里并未能将其另存globals()为字典,我发现您可以使用莳萝库对会话进行腌制。

可以使用以下方法完成:

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

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

我不认为莳萝会保存所有变量,例如,如果您在某个函数中运行dill.dump_session(),则该函数本地的变量不会被保存。
帕萨

3
那只是一个范围问题,我想如果需要的话,您可以将所有locals()追加到globals()上?
user2589273

我收到“ TypeError:无法腌制Socket对象”
R. Cox

1
转储会话时出现以下类型错误: TypeError: no default __reduce__ due to non-trivial __cinit__
Kareem Jeiroudi

我试了一下,发现它不能保存命名数组,尽管这可能是一个限制。
rhody

6

一种很简单的方法可以满足您的需求。对我来说,它做得很好:

只需在“变量资源管理器”(Spider的右侧)上单击此图标:

将所有变量保存为* .spydata格式

加载所有变量或图片等。


我昨天将所有变量保存为.spydata格式,今天尝试导入数据。没有变量被导入:(
Bharat Ram Ammu

这对我有用,但是现在我拥有更多数据,而不是制作Spydata文件,现在制作的内容为零的pickle文件以及成百上千的npy文件。我该如何打开它们?
R. Cox

4

这是使用spyderlib函数保存Spyder工作区变量的方法

#%%  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) 

请让我知道这对你有没有用。大卫·BH


“ NameError:未定义名称'fpath'”:我忘记了什么吗?
托马斯

好主意。我正在考虑从spyder的工作空间借用同一件事。但是不知道怎么做。但是,我不太了解您的代码。您能否告诉我,这是否与Spyder完全自动捕获所有变量一样,还是必须指定要使用的变量?
cqcn1991

2

您试图做的是使您的过程休眠。已经讨论过了。结论是,尝试这样做时存在一些难以解决的问题。例如,恢复打开的文件描述符。

最好为您的程序考虑序列化/反序列化子系统。在许多情况下,这并非微不足道,但从长远来看,它是更好的解决方案。

虽然如果我夸大了这个问题。您可以尝试使全局变量dict腌制。使用globals()访问字典。由于它是变种索引的,因此您不必理会该顺序。


不对 我不是想让进程休眠。我有一个交互式python shell,可以在其中运行几个脚本和命令。我想保存其中一些命令的输出(变量),以便将来在需要访问输出时,可以启动python shell并加载所有这些变量。
user10 2010年

因此,腌制字典var_name-> var_value
nkrkv

0

如果您希望抽象出可以接受的答案,那么可以使用:

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

获取/加载工作空间:

import my_pkg as mp

x=1

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

print x #print 3 for me

它在我运行时有效。我会承认我不明白,dir()而且globals()100%知道,所以我不确定是否可能会有一些怪异的警告,但到目前为止似乎仍然有效。欢迎评论:)


经过更多研究后,如果您save_workspace按照我的建议使用globals进行调用,并且save_workspace该函数在函数内,则无法将其保存在本地范围内,则无法正常工作。对于那个用途locals()。发生这种情况是因为全局变量从定义函数的模块中获取全局变量,而不是从调用函数的地方获取全局变量。


0

您可以将其另存为文本文件或CVS文件。例如,人们使用Spyder保存变量,但存在一个已知问题:对于特定的数据类型,它无法顺利导入。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.