Как сохранить все переменные в текущем сеансе Python?

96

Я хочу сохранить все переменные в моей текущей среде Python. Кажется, один из вариантов - использовать модуль «pickle». Однако я не хочу этого делать по 2 причинам:

  1. Я должен вызывать pickle.dump()каждую переменную
  2. Когда я хочу получить переменные, я должен запомнить порядок, в котором я сохранил переменные, а затем выполнить a pickle.load()для получения каждой переменной.

Я ищу какую-нибудь команду, которая сохранит весь сеанс, чтобы при загрузке этого сохраненного сеанса все мои переменные были восстановлены. Это возможно?

Изменить: я думаю, я не против вызова pickle.dump()каждой переменной, которую я хотел бы сохранить, но запоминание точного порядка, в котором были сохранены переменные, кажется большим ограничением. Я хочу этого избежать.

user10
источник

Ответы:

84

Если вы используете полку , вам не нужно запоминать порядок, в котором объекты мариновались, поскольку 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]
Unutbu
источник
4
Отлично. Это то, что я искал. Кстати, я нахожу это предложение в вашем посте очень забавным: «Положить свою работу на
полку
3
И тут я подумал, что "соленья" смешные! :) en.wikipedia.org/wiki/Inherently_funny_word
unutbu 02
1
Я знаю, что этот ответ - очень старый байт, когда я это делаю, у меня возникает следующая ошибка: PicklingError: Can't pickle <built-in function raw_input>: it's not the same object as __builtin__.raw_inputв моем рабочем пространстве объявлены только две переменные. Есть идеи, как это решить? Есть ли лучший способ сохранить текущий сеанс после этого ответа?
hellter
1
У меня такая же проблема с использованием полки, как описано выше. PicklingError: Can't pickle <type 'numpy.int32'>: это не тот же объект, что и numpy.int32
Пу Чжан
1
Похоже, что некоторые встроенные функции и пакеты нельзя отложить, поэтому просто используйте except:вместо except TypeError:. Это
Nitro,
65

Сидя здесь и не сумев сохранить в globals()качестве словаря, я обнаружил, что вы можете мариновать сеанс, используя библиотеку укропа.

Это можно сделать с помощью:

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

# and to load the session again:
dill.load_session(filename)
user2589273
источник
Я не думаю, что укроп сохраняет все переменные, например, если вы запускаете dill.dump_session () в функции, переменные, локальные для этой функции, не сохраняются.
Parsa
3
Это просто проблема с областью видимости, я думаю, вы могли бы просто добавить все свои locals () в globals (), если нужно?
user2589273 06
Я получил «TypeError: не
Р. Кокс,
1
При сбросе сеанса я получаю следующую ошибку типа: TypeError: no default __reduce__ due to non-trivial __cinit__
Карим Джеруди,
Я попробовал это и обнаружил, что он не может сохранять именованные массивы, хотя это может быть ограничением рассола.
rhody
6

Один очень простой способ, который может удовлетворить ваши потребности. Для меня это очень хорошо:

Просто щелкните этот значок в проводнике переменных (справа от Spider):

Сохранение всех переменных в формате * .spydata

Загрузка всех переменных или изображений и т. Д.

shm2008
источник
Вчера я сохранил все переменные в формате .spydata, а сегодня попытался импортировать данные. Никакая переменная не импортируется :(
Бхарат Рам Амму
Это сработало для меня, но теперь, когда у меня больше данных, он вместо создания файла Spydata теперь создает файл рассола с нулевым содержимым, а также сотни файлов npy. Как мне их открыть?
R. Cox
4

Вот способ сохранения переменных рабочего пространства Spyder с помощью функций 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) 

Сообщите мне, если это сработает для вас. Дэвид Б.Х.

Дэвид Б.Х.
источник
«NameError: имя 'fpath' не определено»: я что-то забыл?
Thomas
Это хорошая идея. Я думал о том, чтобы позаимствовать из рабочего пространства Spyder то же самое. Но не понял как. Однако я не совсем понял ваш код. Не могли бы вы сказать, работает ли это точно так же, как Spyder, что он автоматически улавливает все переменные, или мне нужно указать переменные, которые я хочу использовать?
cqcn1991 06
2

Вы пытаетесь перевести процесс в спящий режим. Об этом уже говорили . Вывод состоит в том, что существует несколько трудных для решения проблем при попытке решить эту проблему. Например, с восстановлением дескрипторов открытых файлов.

Лучше подумать о подсистеме сериализации / десериализации для вашей программы. Во многих случаях это нетривиально, но в долгосрочной перспективе это гораздо лучшее решение.

Хотя если бы я преувеличил проблему. Вы можете попробовать обработать свои глобальные переменные dict . Используйте globals()для доступа к словарю. Поскольку он индексируется по имени переменной, вам не нужно беспокоиться о порядке.

nkrkv
источник
Нет. Я не пытаюсь перевести процесс в спящий режим. У меня есть интерактивная оболочка Python, в которой я запускаю несколько скриптов и команд. Я хочу сохранить выходные данные (переменные) некоторых из этих команд, чтобы в будущем, когда мне понадобится доступ к выходным данным, я мог просто запустить оболочку python и загрузить все эти переменные.
user10 02
Итак, выберите словарь var_name -> var_value
nkrkv 02
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как я предложил, с глобальными save_workspaceобъектами и находитесь в функции, он не будет работать должным образом, если вы хотите сохранить проверяемые в локальной области. Для этого используют locals(). Это происходит потому, что глобальные переменные берут глобальные переменные из модуля, в котором определена функция, а не из того места, где она вызывается.

Пиноккио
источник
0

Вы можете сохранить его как текстовый файл или файл CVS. Например, люди используют Spyder для сохранения переменных, но у него есть известная проблема: для определенных типов данных он не может быть импортирован в будущем.

Навид Фархуди
источник