gpt4 book ai didi

python - Python 中自定义对象数组 pickle 的 TypeError

转载 作者:行者123 更新时间:2023-11-28 22:49:36 24 4
gpt4 key购买 nike

我有以下方法:

def save(self):
vertices = self.mindmap.get_vertices()
edges = self.mindmap.get_edges()

output = open('mindmap.pkl', 'wb')

pickle.dump(edges, output)
pickle.dump(vertices, output)

output.close()

当我调用此方法时,出现以下错误:

Traceback (most recent call last):
File "main.py", line 72, in <module>
MindMapApp().run()
File "/Applications/Kivy.app/Contents/Resources/kivy/kivy/app.py", line 792, in run
runTouchApp()
File "/Applications/Kivy.app/Contents/Resources/kivy/kivy/base.py", line 481, in runTouchApp
EventLoop.window.mainloop()
File "/Applications/Kivy.app/Contents/Resources/kivy/kivy/core/window/window_pygame.py", line 381, in mainloop
self._mainloop()
File "/Applications/Kivy.app/Contents/Resources/kivy/kivy/core/window/window_pygame.py", line 287, in _mainloop
EventLoop.idle()
File "/Applications/Kivy.app/Contents/Resources/kivy/kivy/base.py", line 324, in idle
self.dispatch_input()
File "/Applications/Kivy.app/Contents/Resources/kivy/kivy/base.py", line 309, in dispatch_input
post_dispatch_input(*pop(0))
File "/Applications/Kivy.app/Contents/Resources/kivy/kivy/base.py", line 275, in post_dispatch_input
wid.dispatch('on_touch_up', me)
File "_event.pyx", line 316, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:4537)
File "/Applications/Kivy.app/Contents/Resources/kivy/kivy/uix/behaviors.py", line 110, in on_touch_up
self.dispatch('on_release')
File "_event.pyx", line 312, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:4491)
File "/Applications/Kivy.app/Contents/Resources/kivy/kivy/lang.py", line 1299, in custom_callback
exec(__kvlang__.co_value, idmap)
File "./mindmap.kv", line 14, in <module>
on_release: app.save()
File "main.py", line 27, in save
pickle.dump(vertices, output)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1370, in dump
Pickler(file, protocol).dump(obj)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
self.save(obj)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 600, in save_list
self._batch_appends(iter(obj))
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 615, in _batch_appends
save(x)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 306, in save
rv = reduce(self.proto)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy_reg.py", line 71, in _reduce_ex
state = base(self)
TypeError: __init__() takes exactly 0 positional arguments (1 given)

如果两个数组都为空,我不会收到此错误。生成上述代码时,edges 为空,vertices 的大小为 1。我真的不知道如何解释这个错误,因此也不知道如何解决它。

这是我的 Vertex__init__:

def __init__(self, pos=None, size=None):
super(Vertex, self).__init__()

self.pos = pos
self.size = size

if self.height < self.MINIMUM_HEIGHT + self.TEXT_OFFSET:
self.height = self.MINIMUM_HEIGHT + self.TEXT_OFFSET

if self.width < self.MINIMUM_WIDTH + self.TEXT_OFFSET:
self.width = self.MINIMUM_WIDTH + self.TEXT_OFFSET

self.originalSize = self.size
self.originalWidth = self.size[0]

self.newIdea = TextInput(
height = self.MINIMUM_HEIGHT,
size_hint = (None, None),
pos_hint = {'center_x':.5, 'center_y':.5},

background_active = '',
background_normal = '',

use_bubble = True,

foreground_color = (.4, .4, .4, 1),
cursor_color = (.4, .4, .4, 1))
self.newIdea.bind(text=self.on_text)

self.idea = Label(
height = self.MINIMUM_HEIGHT,
size_hint = (None, None),
pos_hint = {'center_x':.5, 'center_y':.5},
color = (.4, .4, .4,1))

Logger.info('Vertex: created')

最佳答案

确实,Kivy EventDispatcher 对象在这里有问题; object.__reduce_ex__ method搜索第一个不是自定义类的基类(它没有设置了Py_TPFLAGS_HEAPTYPE标志),以在该类上调用__init__这对于该基类失败了,因为它的 __init__ 方法不支持传入单个参数。

解决方法是改用最新的 pickle 协议(protocol);它使用不同的代码路径:

pickle.dump(edges, output, pickle.HIGHEST_PROTOCOL)
pickle.dump(vertices, output, pickle.HIGHEST_PROTOCOL)

因为最新的 pickle 协议(protocol) (2) 更有效地支持新型类。

看到Kivy对象层次结构的复杂性,你可能需要自定义pickling过程。

我会考虑实现 __getnewargs__ method例如:

def __getnewargs__(self):
return (self.pos, self.size)

将确保只有数据被 pickle ,仅此而已。在 unpickling 时,这两个值随后用于创建 Vertex 对象。请注意,要使用此方法,您必须使用最新的协议(protocol)!

您还可以实现 __getstate__ method ;如果您返回字典,则不需要镜像 __setstate__ 方法,但允许您初始化更多属性。

如果两者都没有实现,实例 __dict__ 的内容将被 pickle 。确保包含的所有内容都可以 pickle 。

关于python - Python 中自定义对象数组 pickle 的 TypeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23633932/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com