【问题标题】:How to save all the variables in the current python session?如何保存当前python会话中的所有变量?
【发布时间】:2011-02-27 00:00:14
【问题描述】:

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

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

我正在寻找一些可以保存整个会话的命令,这样当我加载这个保存的会话时,我的所有变量都会恢复。这可能吗?

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

【问题讨论】:

    标签: python save


    【解决方案1】:

    如果您使用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]
    

    【讨论】:

    • 完美。这就是我一直在寻找的。顺便说一句,我觉得你帖子中的这句话非常有趣:“搁置你的工作”:)
    • 我觉得“泡菜”很有趣! :) en.wikipedia.org/wiki/Inherently_funny_word
    • 我知道这个答案是非常旧的,当我这样做时我有以下错误:PicklingError: Can't pickle <built-in function raw_input>: it's not the same object as __builtin__.raw_input 我的工作区中只声明了 2 个变量。关于如何解决这个问题的任何想法?在这个答案之后有更好的方法来保存当前会话吗?
    • 我在使用搁置时遇到了同样的问题,如上所述。 PicklingError: Can't pickle : it's not the same object as numpy.int32
    • 有些内置函数和包似乎无法搁置,所以只需使用except: 而不是except TypeError:。这将搁置用户定义的变量和大多数对象(熊猫数据框对我来说搁置很好)
    【解决方案2】:

    坐在这里并未能将globals() 保存为字典,我发现您可以使用 dill 库腌制会话。

    这可以通过使用来完成:

    import dill                            #pip install dill --user
    filename = 'globalsave.pkl'
    dill.dump_session(filename)
    
    # and to load the session again:
    dill.load_session(filename)
    

    【讨论】:

    • 我不认为 dill 会保存所有变量,例如,如果您在函数中运行 dill.dump_session(),则不会保存该函数的本地变量。
    • 这只是一个范围问题,我想如果必须的话,您可以将所有 locals() 附加到 globals() 中?
    • 我收到“TypeError: can't pickle Socket objects”
    • 转储会话时出现以下类型错误:TypeError: no default __reduce__ due to non-trivial __cinit__
    • 我试过这个,发现它无法保存命名数组,尽管这可能是一个泡菜限制。
    【解决方案3】:

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

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

    Saving all the variables in *.spydata format

    Loading all the variables or pics etc.

    【讨论】:

    • 昨天我把所有的变量都保存成 .spydata 格式,今天我试着导入数据。没有变量被导入:(
    • 这对我有用,但现在我有更多的数据,而不是制作一个 Spydata 文件,现在制作一个零内容的泡菜文件以及数百个 npy 文件。请问如何打开这些?
    【解决方案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) 
    

    让我知道它是否适合您。 大卫 B-H

    【讨论】:

    • "NameError: name 'fpath' is not defined": 我是不是忘了什么?
    • 这是个好主意。我正在考虑从 spyder 的工作区借用同样的东西。但是不知道怎么弄。但是,我不太了解您的代码。你能告诉我,它是否像 Spyder 一样工作,它会自动捕获所有变量,或者我必须指定我想要使用的变量?
    【解决方案5】:

    您要做的是使您的进程休眠。这已经是discussed。结论是,在尝试这样做时存在几个难以解决的问题。例如恢复打开的文件描述符。

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

    虽然我夸大了这个问题。你可以尝试腌制你的全局变量dict。使用globals() 访问字典。由于它是 varname-indexed,因此您不必担心订单。

    【讨论】:

    • 不。我不想让这个过程休眠。我有一个交互式 python shell,我在上面运行了几个脚本和命令。我想保存其中一些命令的输出(变量),这样以后每当我需要访问输出时,我就可以启动一个 python shell 并加载所有这些变量。
    • 所以,腌制字典 var_name -> var_value
    【解决方案6】:

    如果您希望将接受的答案抽象为功能,您可以使用:

        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 并且 save_workspace 在函数内,如果您想将变量保存在本地范围内,它将无法按预期工作。为此使用locals()。发生这种情况是因为 globals 从定义函数的模块中获取全局变量,而不是从调用它的地方获取全局变量是我的猜测。

    【讨论】:

      【解决方案7】:

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

      【讨论】:

        猜你喜欢
        • 2011-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-09
        • 1970-01-01
        • 2012-05-17
        相关资源
        最近更新 更多