Як зберегти та відновити кілька змінних у python?


105

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

Редагувати.
Усі об'єкти, які я намагався зберегти, були в одному класі (я повинен був це згадати раніше), і я не розумів, що я можу просто зберегти весь клас так:

import pickle
def saveLoad(opt):
    global calc
    if opt == "save":
        f = file(filename, 'wb')
        pickle.dump(calc, f, 2)
        f.close
        print 'data saved'
    elif opt == "load":
        f = file(filename, 'rb')
        calc = pickle.load(f)
    else:
        print 'Invalid saveLoad option'

1
Ви кажете, що ви пробували цикл. Будь ласка, опублікуйте цей код і чому "він не працював правильно" (тобто, що сталося і що ви хотіли).
Блер

Якщо ви перебуваєте у вікні, не забудьте відкрити файли у двійковому режимі
Джон Ла Рой

@gnibbler: бінарний режим потрібен лише для протоколів, які не за замовчуванням ( docs.python.org/library/pickle.html#usage ).
Eric O Lebigot

Відповіді:


170

Якщо вам потрібно зберегти декілька об'єктів, ви можете просто поставити їх в один список, або кортеж, наприклад:

import pickle

# obj0, obj1, obj2 are created here...

# Saving the objects:
with open('objs.pkl', 'w') as f:  # Python 3: open(..., 'wb')
    pickle.dump([obj0, obj1, obj2], f)

# Getting back the objects:
with open('objs.pkl') as f:  # Python 3: open(..., 'rb')
    obj0, obj1, obj2 = pickle.load(f)

Якщо у вас багато даних, ви можете зменшити розмір файлу, перейшовши protocol=-1до dump(); pickleтоді буде використаний найкращий доступний протокол замість протоколу за замовчуванням (та більш сумісного з протоколом). У цьому випадку файл повинен відкриватися у двійковому режимі ( wbі rbвідповідно).

Бінарний режим також слід використовувати з Python 3, оскільки його протокол за замовчуванням створює двійкові (тобто нетекстові) дані (режим запису 'wb'та режим читання 'rb').


12
У Python 3.5 мені довелося відкривати файл у режимі "байт", наприклад with open('objs.pickle', 'wb') as f:(зверніть увагу на wb).
кбросе

Привіт @Eric, з чим with open('objs.pkl') as f:просто порівняти obj1, obj2 = pickle.load(open("objs.pkl","rb"))? Чи є різниця між цими двома?
balandongiv

З другою формою ви не закриваєте файл. Це не вважається хорошою практикою, оскільки кількість файлів, які можна відкрити паралельно, зазвичай досить обмежена операційними системами (спробуйте цикл, який відкриває файли, не закриваючи їх!). Однак на практиці часто закриття файлу працює, коли ви не відкриваєте багато файлів.
Ерік О Лебігот

51

Є вбудована бібліотека під назвою pickle. Використовуючи pickleви можете скинути об’єкти у файл та завантажити їх пізніше.

import pickle

f = open('store.pckl', 'wb')
pickle.dump(obj, f)
f.close()

f = open('store.pckl', 'rb')
obj = pickle.load(f)
f.close()

1
Я використовую Python 3.4: f = open('store.pckl', 'wb')щоб відкрити файл для запису. Зверніться до stackoverflow.com/questions/13906623/… І використовуйте `f = open ('store.pckl', 'rb'), щоб відкрити файл для читання. Зверніться до stackoverflow.com/questions/7031699/… .
користувач3731622

це специфічно для 3,4+? Я майже проголосував відповідь, оскільки вона створює помилки, коли ви не використовуєте "b".
Вільмер Е. Енао

12

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


Я хочу зберегти один об’єкт, який входить на хмарний сервер, щоб обробляти, якщо я входитиму кілька разів за час, сервер відхиляє мій запит. Чи може зберігати об’єкт у файл за допомогою модуля маринування, який може мати проблеми із захистом? , наприклад, якщо хтось отримає мій викинутий об'єкт, він може увійти в мою хмарну пам’ять без використання пароля.
альпер

5

Інший підхід до збереження декількох змінних у файлі соління:

import pickle

a = 3; b = [11,223,435];
pickle.dump([a,b], open("trial.p", "wb"))

c,d = pickle.load(open("trial.p","rb"))

print(c,d) ## To verify

4

Ви можете використовувати klepto, що забезпечує стійке кешування пам’яті, диску чи базі даних.

dude@hilbert>$ python
Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from klepto.archives import file_archive
>>> db = file_archive('foo.txt')
>>> db['1'] = 1
>>> db['max'] = max
>>> squared = lambda x: x**2
>>> db['squared'] = squared
>>> def add(x,y):
...   return x+y
... 
>>> db['add'] = add
>>> class Foo(object):
...   y = 1
...   def bar(self, x):
...     return self.y + x
... 
>>> db['Foo'] = Foo
>>> f = Foo()
>>> db['f'] = f  
>>> db.dump()
>>> 

Потім після перезапуску перекладача ...

dude@hilbert>$ python
Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from klepto.archives import file_archive
>>> db = file_archive('foo.txt')
>>> db
file_archive('foo.txt', {}, cached=True)
>>> db.load()
>>> db
file_archive('foo.txt', {'1': 1, 'add': <function add at 0x10610a0c8>, 'f': <__main__.Foo object at 0x10510ced0>, 'max': <built-in function max>, 'Foo': <class '__main__.Foo'>, 'squared': <function <lambda> at 0x10610a1b8>}, cached=True)
>>> db['add'](2,3)
5
>>> db['squared'](3)
9
>>> db['f'].bar(4)
5
>>> 

Отримати код можна тут: https://github.com/uqfoundation


7
ОП не просила вбудованого.
Майк Маккернс

4

Наступний підхід видається простим і може бути використаний із змінними різного розміру:

import hickle as hkl
# write variables to filename [a,b,c can be of any size]
hkl.dump([a,b,c], filename)

# load variables from filename
a,b,c = hkl.load(filename)

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