【问题标题】:What is pickle doing?泡菜在做什么?
【发布时间】:2018-11-28 23:46:56
【问题描述】:

我已经使用 Python 多年了。我已经广泛使用泡菜。我不知道这是在做什么:

with codecs.open("huge_picklefile.pc", "rb") as f:
    data = pickle.load(f)
    print(len(data))
    data = pickle.load(f)
    print(len(data))
    data = pickle.load(f)
    print(len(data))

这会返回给我:

335
59
12

我很困惑。我习惯将大量文件加载到内存中。对象本身是一个庞大的数组数组(我假设)。它可以由多个泡菜对象组成吗?不幸的是,我没有创建泡菜对象,也无权访问是谁创建的。

我无法弄清楚为什么 pickle 将我的文件分成块,这不是默认设置,我也没有告诉它。重新加载同一个文件有什么作用?老实说,到目前为止,我从未尝试过甚至遇到过用例。

我花了 5 个小时试图弄清楚如何在 Google 上提出这个问题。毫不奇怪,尝试“在同一个文档上加载多个泡菜”不会产生任何有用的东西。 Python 3.7 pickle 文档没有描述这种行为。我无法弄清楚重复加载泡菜文档不会(a)崩溃或(b)将整个内容加载到内存中然后仅引用自身。在我使用 python 的 15 年中,我从未遇到过这个问题......所以我相信这很奇怪,我们可能应该只使用数据库来代替。

【问题讨论】:

  • 不确定这是否可行,但通过查看Python 3.7 Pickle 的文档,答案可能是调用pickle.load(f, *) 一次加载所有目标文件?
  • @MaxCollier:这不是有效的语法。我认为您误读了函数签名。函数签名中的* 指定仅关键字参数的开头。您不能将 * 作为参数传递给函数。
  • pickle 将一次加载一个对象。如果有人完成了pickle.dump(f, obj) ob 文件来创建它,则可能会有进一步的序列化对象。有些人这样做,出于某种奇怪的原因。我想,很容易序列化各种对象并读入并以这种方式懒惰地处理它们,但使用shelve之类的东西可能会更好

标签: python python-3.x pickle


【解决方案1】:

这个文件不是一个pickle文件。有人将多个泡菜转储到同一个文件中,导致文件内容是多个泡菜的串联。当你调用pickle.load(f) 时,pickle 会从当前文件位置读取文件,直到找到一个pickle 结尾,所以每个pickle.load 调用都会加载下一个pickle。

您可以通过反复调用pickle.dump 自己创建这样的文件:

with open('demofile', 'wb') as f:
    pickle.dump([1, 2, 3], f)
    pickle.dump([10, 20], f)
    pickle.dump([0, 0, 0], f)

【讨论】:

  • 我相信这是pickle设计的一部分,但无论如何,应该使用shelve来实现这一点
猜你喜欢
  • 1970-01-01
  • 2014-03-12
  • 2012-12-02
  • 2017-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多