使用 pickle 转储 gtk.ListStore 的子类
我正在尝试使用 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__ 函数。据我了解文档,这应该优先用于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'),'w') as f:
pickle.dump(x,f)
在每种情况下,pickle.dump 都会引发 TypeError,“无法 pickle ListStore 对象”。使用 print 语句,我已经验证了使用 pickle.dump 时 __getstate__
函数正在运行。我没有从文档中看到任何关于下一步该做什么的提示,所以我有点困惑。有什么建议吗?
I am trying to dump a custom class using pickle. The class was subclassed from gtk.ListStore, since that made it easier to store particular data and then display it using gtk. This can be reproduced as shown here.
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)
The solution that I have tried was to add a __getstate__
function into my class. As far as I understand the documentation, this should take precedence for pickle so that it no longer tries to serialize the ListStore, which it is unable to do. However, I still get an identical error from pickle.dump when I try to pickle my object. The error can be reproduced as follows.
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)
In each case, pickle.dump raises a TypeError, "can't pickle ListStore objects". Using print statements, I have verified that the __getstate__
function is run when using pickle.dump. I don't see any hints as to what to do next from the documentation, and so I'm in a bit of a bind. Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通过这种方法,您甚至可以使用 json 而不是 pickle 来达到您的目的。
这是一个快速工作示例,向您展示了pickle“不可picklable类型”(如
gtk.ListStore
)所需的步骤。本质上,您需要做一些事情:self.get_column_type(0)
返回一个 Gtype,因此您需要将其映射回相应的 Python 类型。我将其作为练习 - 在我的示例中,我采用了一种技巧来从第一行值中获取列类型。_new_foo
函数将需要重建实例。示例:
输出:
With this method you can even use json instead of pickle for your purpose.
Here is a quick working example to show you the steps you need to employ to pickle "unpicklable types" like
gtk.ListStore
. Essentially you need to do a few things:__reduce__
which returns a function and arguments needed to reconstruct the instance.self.get_column_type(0)
returns a Gtype, so you will need to map this back to the corresponding Python type. I've left that as an exercise - in my example I've employed a hack to get the column types from the first row of values._new_foo
function will need to rebuild the instance.Example:
Output:
当您子类化对象时,
object.__reduce__
负责调用__getstate__
。看起来,由于这是 gtk.ListStore 的子类,因此 __reduce__ 的默认实现会尝试 pickle 数据以重建 gtk.ListStore 。 > 首先对象,然后调用您的__getstate__
,但由于gtk.ListStore
无法进行 pickle,因此它拒绝对您的类进行 pickle。如果您尝试实现__reduce__
和__reduce_ex__
而不是__getstate__
,问题就会消失。此外,您可以尝试考虑其他序列化程序,例如
json
。在那里,您可以通过自己定义自定义类的序列化方式来完全控制序列化过程。另外,默认情况下,它们不存在pickle
的安全问题。When you subclass object,
object.__reduce__
takes care of calling__getstate__
. It would seem that since this is a subclass ofgtk.ListStore
, the default implementation of__reduce__
tries to pickle the data for reconstructing agtk.ListStore
object first, then calls your__getstate__
, but since thegtk.ListStore
can't be pickled, it refuses to pickle your class. The problem should go away if you try to implement__reduce__
and__reduce_ex__
instead of__getstate__
.As an addition, you may try to consider other serializers, such as
json
. There you take full control of the serialiazaton process by defining how custom classes are to be serialized yourself. Plus by default they come without the security issues ofpickle
.