Python - Pickle init需要4个参数 - 给出1个

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python - Pickle init需要4个参数 - 给出1个相关的知识,希望对你有一定的参考价值。

每当我尝试加载一个pickle对象时,我都会收到此错误:

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "renpy/common/00action_file.rpy", line 328, in __call__
    renpy.load(fn)
TypeError: __init__() takes exactly 4 arguments (1 given)

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "renpy/common/_layout/screen_main_menu.rpym", line 29, in script
    $ ui.interact()
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/ast.py", line 785, in execute
    renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/python.py", line 1382, in py_exec_bytecode
    exec bytecode in globals, locals
  File "renpy/common/_layout/screen_main_menu.rpym", line 29, in <module>
    $ ui.interact()
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/ui.py", line 247, in interact
    rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/display/core.py", line 2149, in interact
    repeat, rv = self.interact_core(preloads=preloads, **kwargs)
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/display/core.py", line 2750, in interact_core
    rv = root_widget.event(ev, x, y, 0)
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/display/layout.py", line 846, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/display/layout.py", line 846, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/display/layout.py", line 846, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/display/screen.py", line 626, in event
    rv = self.child.event(ev, x, y, st)
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/display/layout.py", line 846, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/display/layout.py", line 846, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/display/layout.py", line 846, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/display/behavior.py", line 762, in event
    return handle_click(self.clicked)
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/display/behavior.py", line 705, in handle_click
    rv = run(action)
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/display/behavior.py", line 274, in run
    return var(*args, **kwargs)
  File "renpy/common/00action_file.rpy", line 328, in __call__
    renpy.load(fn)
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/loadsave.py", line 573, in load
    roots, log = loads(location.load(filename))
  File "/home/digiholic/workspace/SummonerSweetheart-0.9-all/renpy/loadsave.py", line 51, in loads
    return pickle.loads(s)
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/pickle.py", line 1382, in loads
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/pickle.py", line 858, in load
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/pickle.py", line 1133, in load_reduce
TypeError: __init__() takes exactly 4 arguments (1 given)

Linux-3.11.0-26-generic-x86_64-with-debian-wheezy-sid
Ren'Py 6.18.3.761
Summoner Sweetheart 0.9

我目前正在使用Renpy,一个pygame框架。游戏加载并保存得很好,直到我达到加载我编码的外部对象的程度。加载该对象后,pickle将游戏状态保存正常,但无法加载它,从而给出了上述错误。

我知道没有太多可以继续下去,但这个错误在我的联盟中是如此,我甚至不知道问题代码可能在哪里。

答案

你没有正确使用__reduce__。见这里:https://docs.python.org/2/library/pickle.html#object.reduce。对于类,您可以返回class的元组和要传递给args__init__。在这里查看https://github.com/uqfoundation/mystic/blob/6bfbc46f9094f96deae020074d7bdad2a43d91d6/mystic/monitors.py#L298的例子。您还可以使用__setstate__方法,以获得更复杂的类行为。

最小的例子:

>>> class Foo(object):
...   def __init__(self, x, y, z):
...     self.x = x
...     self.y = y
...     self.z = z
...   def __reduce__(self):
...     return (self.__class__, (self.x, self.y, self.z))
...   f = lambda x:x
... 
>>> f = Foo(1,2,3)
>>> 
>>> import pickle
>>> _f = pickle.loads(pickle.dumps(f))
>>> _f.x, _f.y, _f.z
(1, 2, 3)
>>> 

但是,如果你有很多不可打击的项目,通常最简单的方法是使用更好的序列化程序,如dill(参见这里:https://github.com/uqfoundation/dill

另一答案

我有同样的问题。问题在于字节对象如何在python中工作。

我不知道真正的问题来自哪里,但如果你自己将那个腌制对象打印为字节字符串(b'blahblah')并直接将其提供给pickle.loads(b'blahblah'),你会得到同样的错误。

有些对象似乎不能以这种方式工作,它们不能被序列化,保存,然后再次反序列化(可能是因为它们的依赖性或其他东西)。

我对那些想要使用pickle转储对象的人的建议是简单地避免使用它。 这不值得你花时间。

  1. 只需保存必要的属性,然后再使用其构造函数再次从这些值重新创建该对象。
  2. 或者您可以使用ORM工具为您管理。

希望这能节省一些时间。

以上是关于Python - Pickle init需要4个参数 - 给出1个的主要内容,如果未能解决你的问题,请参考以下文章

python pickle模块

python pickle 序列化类

pickle模块

Python pickle 协议选择?

python pickle 上的命名空间

Python pickle 如何保存对象?