加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

使用pickle转储gtk.ListStore的子类

发布时间:2020-12-20 13:23:17 所属栏目:Python 来源:网络整理
导读:我正在尝试使用pickle转储自定义类.该类是从gtk.ListStore子类化的,因为这样可以更容易地存储特定数据,然后使用gtk显示它.这可以如此处所示再现. import gtkimport pickleimport osclass foo(gtk.ListStore): passif __name__=='__main__': x = foo(str) wit
我正在尝试使用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.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'),f)

在每种情况下,pickle.dump引发一个TypeError,“不能pickle ListStore对象”.使用print语句,我已经验证了使用pickle.dump时运行了__getstate__函数.我没有看到关于文档中接下来要做什么的任何提示,所以我有点绑定.有什么建议?

解决方法

使用这种方法,您甚至可以使用json代替pickle.

这是一个快速工作的示例,向您展示了需要采用的步骤来挑选像gtk.ListStore这样的“无法解决的类型”.基本上你需要做一些事情:

>定义__reduce__,它返回重建实例所需的函数和参数.
>确定ListStore的列类型. self.get_column_type(0)方法返回一个Gtype,因此您需要将其映射回相应的Python类型.我把它留作练习 – 在我的例子中,我使用了一个hack从第一行的值中获取列类型.
>您的_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__,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]

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读