Як зберегти всі змінні в поточному сеансі python?


95

Я хочу зберегти всі змінні в моєму поточному середовищі python. Здається, одним із варіантів є використання модуля 'соління'. Однак я не хочу робити це з двох причин:

  1. Я повинен зателефонувати pickle.dump()за кожною змінною
  2. Коли я хочу отримати змінні, я повинен пам’ятати, в якому порядку я зберігав змінні, а потім зробити a pickle.load()для отримання кожної змінної.

Я шукаю якусь команду, яка б зберегла весь сеанс, так що при завантаженні цього збереженого сеансу всі мої змінні будуть відновлені. Чи можливо це?

Редагувати: Я думаю, я не проти зателефонувати pickle.dump()до кожної змінної, яку я хотів би зберегти, але запам'ятовувати точний порядок збереження змінних здається великим обмеженням. Я хочу цього уникнути.

Відповіді:


83

Якщо ви використовуєте полицю , вам не доведеться запам'ятовувати порядок маринування предметів, оскільки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
Ідеально Це те, що я шукав. До речі, я вважаю це речення у вашому дописі надзвичайно смішним: "To
police police

3
І тут мені здалося, що «соління» смішні! :) en.wikipedia.org/wiki/Inherently_funny_word
unutbu

1
Я знаю, що ця відповідь дуже стара byt, коли я це роблю, у мене є така помилка: у PicklingError: Can't pickle <built-in function raw_input>: it's not the same object as __builtin__.raw_inputмене просто є 2 змінні, оголошені в моїй робочій області. Будь-які ідеї щодо того, як це вирішити? Чи з’явився якийсь кращий спосіб зберегти поточний сеанс після цієї відповіді?
hellter

1
У мене така сама проблема щодо використання полиці, як описано вище. PicklingError: Не вдається замаринувати <type 'numpy.int32'>: це не той самий об'єкт, що і numpy.int32
Пу Чжан,

1
Схоже, деякі вбудовані функції та пакети не можна буде відкласти, тому просто використовуйте except:замість except TypeError:. Це заблокує визначені користувачем змінні та більшість об’єктів (рамки даних pandas для мене добре відкладені)
Нітро

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)

Я не думаю, що dill зберігає всі змінні, наприклад, якщо ви запустите dill.dump_session () у змінних функції, які є локальними для цієї функції, не зберігаються.
Парса

3
Це лише проблема сфери дії, я думаю, ви могли б просто додати всіх своїх місцевих жителів () до глобальних (), якщо потрібно?
user2589273 06

Я отримав "TypeError: не вдається замаринувати об'єкти Socket"
Р. Кокс,

1
Я отримую таку помилку типу при скиданні сесії: TypeError: no default __reduce__ due to non-trivial __cinit__
Карім Джейруді,

Я спробував це і виявив, що він не може зберегти іменовані масиви, хоча це може бути обмеженням маринування.
Роді

6

Один дуже простий спосіб задовольнити ваші потреби. Для мене це вдалося досить добре:

Просто натисніть на цей значок у Провіднику змінних (праворуч від Spider):

Збереження всіх змінних у форматі * .spydata

Завантаження всіх змінних чи зображень тощо


Вчора я зберег усі змінні у форматі .spydata і сьогодні спробував імпортувати дані. Жодна змінна не імпортується :(
Бхарат Рам Амму,

Це працювало для мене, але тепер, коли я маю більше даних, він замість того, щоб створювати файл Spydata, тепер робить файл розсолу з нульовим вмістом, а також сотні файлів npy. Як мені відкрити їх, будь ласка?
Р. Кокс,

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' не визначено": я щось забув?
Томас

Це хороша ідея. Я думав про те, щоб запозичити у робочому просторі шпигуна те саме. Але не зрозумів, як. Однак я не зовсім зрозумів ваш код. Не могли б ви сказати, чи працює це точно так само, як Spyder, що він автоматично ловить всі змінні, або я повинен вказати змінні, які я хочу використовувати?
cqcn1991

2

Що ви намагаєтеся зробити, це перевести ваш процес у сплячий режим. Це було обговорено вже . Висновок полягає в тому, що існує кілька важко вирішуваних проблем, які намагаються це зробити. Наприклад, з відновленням дескрипторів відкритих файлів.

Краще подумати про підсистему серіалізації / десеріалізації для вашої програми. У багатьох випадках це нетривіально, але є набагато кращим рішенням у довгостроковій перспективі.

Хоча якщо я перебільшив проблему. Ви можете спробувати замаринувати глобальні змінні dict . Використовуйте globals()для доступу до словника. Оскільки він індексується varname, вам не потрібно турбуватися про замовлення.


Ні. Я не намагаюся перезимувати процес. У мене є інтерактивна оболонка python, на якій я запускаю кілька сценаріїв та команд. Я хочу зберегти вихідні дані (змінні) деяких з цих команд, щоб у майбутньому, коли мені потрібен доступ до вихідних даних, я міг просто запускати оболонку python і завантажувати всі ці змінні.
user10 02

Отже, замаринуйте словник 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як я запропонував з глобалами, і save_workspaceє в межах функції, це не спрацює, як очікувалося, якщо ви хочете зберегти змінні в локальній області. Для цього використання locals(). Це трапляється тому, що globals приймає globals з модуля, де визначена функція, а не з того місця, де вона викликається, моє припущення.


0

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.