【问题标题】:How do I save and restore multiple variables in python?如何在 python 中保存和恢复多个变量?
【发布时间】:2011-09-27 22:07:24
【问题描述】:

我需要将十几个对象保存到一个文件中,然后再将它们恢复。 我尝试使用 for 循环与 pickle 和 shelve,但它不能正常工作。

编辑。
我试图保存的所有对象都在同一个类中(我之前应该提到这一点),我没有意识到我可以像这样保存整个类:

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'

【问题讨论】:

  • 您说您尝试了 for 循环。请发布该代码,以及为什么“它不能正常工作”(即发生了什么以及您想要发生什么)。
  • 如果您在 Windows 上,请确保以二进制模式打开文件
  • @gnibbler:只有非默认协议(docs.python.org/library/pickle.html#usage)才需要二进制模式。

标签: python variables object


【解决方案1】:

另一种将多个变量保存到 pickle 文件的方法是:

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

【讨论】:

  • 这不会安全地关闭文件。 open 生成需要关闭的文件句柄,方法是存储句柄并在其上调用.close,或者最好使用with open(...) as ...:。第二个选项通常更好,因为它会自动为您关闭文件,即使发生异常。
【解决方案2】:

以下方法看起来很简单,可以与不同大小的变量一起使用:

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 更健壮(更不容易出错)甚至更简单(更少代码)。
【解决方案3】:

如果您需要保存多个对象,您可以简单地将它们放在一个列表或元组中,例如:

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 然后将使用最佳可用协议,而不是默认的历史(和更向后兼容)协议。在这种情况下,文件必须以二进制模式打开(分别为wbrb)。

二进制模式也应该与 Python 3 一起使用,因为它的默认协议会生成二进制(即非文本)数据(写入模式 'wb' 和读取模式 'rb')。

【讨论】:

  • 在 Python 3.5 中,我必须以“字节”模式打开文件,例如with open('objs.pickle', 'wb') as f:(注意wb)。
  • 嗨@Eric,与简单的obj1, obj2 = pickle.load(open("objs.pkl","rb")) 相比,with open('objs.pkl') as f: 的需要是什么?这两者有什么区别吗?
  • 使用第二种形式,您不会关闭文件。这不是好的做法,因为您可以并行打开的文件数量通常受到操作系统的限制(尝试打开文件而不关闭文件的循环!)。也就是说,实际上,当您不打开很多文件时,通常不关闭文件是可行的。
【解决方案4】:

有一个名为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()

【讨论】:

  • 我 Python 3.4 使用:f = open('store.pckl', 'wb') 打开要写入的文件。参考stackoverflow.com/questions/13906623/… 并使用 `f = open('store.pckl', 'rb') 打开要读取的文件。参考stackoverflow.com/questions/7031699/…
  • 这是特定于 3.4+ 的吗?我几乎否决了这个答案,因为当你不使用“b”时它会产生错误。
  • 问题是“如何在 python 中保存和恢复多个变量?”请更新您的答案如何处理泡菜中的多个变量,而不是一个变量。
【解决方案5】:

您可以使用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

【讨论】:

  • OP 没有要求内置。
【解决方案6】:

您应该查看shelvepickle 模块。如果您需要存储大量数据,最好使用数据库

【讨论】:

  • 我想保存一个登录到云服务器的对象,以便处理如果我随着时间的推移多次登录,服务器会拒绝我的请求。使用 pickle 模块将对象转储到文件中可能有任何安全问题吗? ,例如,如果有人获得了我的转储对象,他们可以不使用密码登录到我的云存储。
猜你喜欢
  • 1970-01-01
  • 2011-03-14
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多