python - 使用 pickle 转储 gtk.ListStore 的子类

标签 python gtk pickle getstate

我正在尝试使用 pickle 转储自定义类。该类是 gtk.ListStore 的子类,因为这样可以更轻松地存储特定数据,然后使用 gtk 显示它。这可以按此处所示进行复制。

import gtk
import pickle
import os

class foo(gtk.ListStore):
    pass

if __name__=='__main__':
    x = foo(str)
    with open(os.path.expandvars('%userprofile%\\temp.txt'),'w') as f:
        pickle.dump(x,f)

我尝试过的解决方案是在我的类中添加一个 __getstate__ 函数。据我了解 documentation ,这应该优先于 pickle,这样它就不再尝试序列化它无法做到的 ListStore。但是,当我尝试 pickle 我的对象时,我仍然从 pickle.dump 得到相同的错误。错误可以重现如下。

import gtk
import pickle
import os

class foo(gtk.ListStore):
    def __getstate__(self):
        return 'bar'

if __name__=='__main__':
    x = foo(str)
    with open(os.path.expandvars('%userprofile%\\temp.txt'),'w') as f:
        pickle.dump(x,f)

在每种情况下,pickle.dump 都会引发 TypeError,“无法 pickle ListStore 对象”。使用 print 语句,我已验证 __getstate__ 函数在使用 pickle.dump 时运行。我没有从文档中看到任何关于下一步该做什么的提示,所以我有点手足无措。有什么建议吗?

最佳答案

通过这种方法,您甚至可以使用 json 而不是 pickle 来达到您的目的。

这是一个快速工作示例,向您展示了 pickle “不可 pickle 类型”(如 gtk.ListStore)所需的步骤。本质上,您需要做几件事:

  1. 定义 __reduce__ 返回重建实例所需的函数和参数。
  2. 确定您的 ListStore 的列类型。 self.get_column_type(0) 方法返回一个 Gtype,因此您需要将其映射回相应的 Python 类型。我将其留作练习 - 在我的示例中,我使用了一种 hack 从第一行值中获取列类型。
  3. 您的 _new_foo 函数需要重建实例。

例子:

import gtk, os, pickle

def _new_foo(cls, coltypes, rows):
    inst = cls.__new__(cls)
    inst.__init__(*coltypes)
    for row in rows:
        inst.append(row)
    return inst

class foo(gtk.ListStore):

    def __reduce__(self):
        rows = [list(row) for row in self]
        # hack - to be correct you'll really need to use 
        # `self.get_column_type` and map it back to Python's 
        # corresponding type.
        coltypes = [type(c) for c in rows[0]]
        return _new_foo, (self.__class__, coltypes, rows)

x = foo(str, int)
x.append(['foo', 1])
x.append(['bar', 2])

s = pickle.dumps(x)

y = pickle.loads(s)
print list(y[0])
print list(y[1])

输出:

['foo', 1]
['bar', 2]

关于python - 使用 pickle 转储 gtk.ListStore 的子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5968204/

相关文章:

python - 在 python 3.6+ 和 PyQt5 中 pickle QPolygon

python - 在 Python 中切换

gtksourceview 中的代码折叠

c++ - 连接到 Gtk::Window signal_delete_event

python - 如何加载带有自定义损失的keras "history"对象?

python - 如何将 python 字典 pickle 到 MySQL 中?

python - 如何处理 pycurl.error - 超时异常?

python - 在 Python 中, Pandas 。如何通过 WOM - 'Week of the Month' 对数据框进行子集化?

python - 如何区分 Pandas 中除一列之外的两个数据框?

c - Glade、GtkBuiler 或 Gtk 意外地交换了信号处理程序