python - 如何 pickle 回调链

标签 python twisted pickle deferred

我在 Twisted 中有一个用户定义的状态机。用户可以为不同的状态更改定义处理程序,我通过使用 Twisted deferred 来实现,我让他们向其中添加回调。每当我从一种状态移动到另一种状态时,我只需触发适当的延迟。

项目要求之一是能够将此状态机及其所有回调保存到磁盘。我以为我可以简单地 pickle 状态机就可以了,但是当我尝试序列化用户定义的函数时我得到了一个 PickleError。

有人知道序列化函数的方法吗?该错误在以下代码示例中重现:

import pickle
from twisted.internet.utils import defer

def foo(*args):
  def bar():
    print args
  return bar

d = defer.Deferred()
d.addCallback(foo("Hello", "world"))
pickle.dumps(d)

这最后一行给出了以下错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/pickle.py", line 1366, in dumps
    Pickler(file, protocol).dump(obj)
  File "/usr/lib/python2.5/pickle.py", line 224, in dump
    self.save(obj)
  File "/usr/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.5/pickle.py", line 725, in save_inst
    save(stuff)
  File "/usr/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.5/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/usr/lib/python2.5/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/usr/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.5/pickle.py", line 600, in save_list
    self._batch_appends(iter(obj))
  File "/usr/lib/python2.5/pickle.py", line 615, in _batch_appends
    save(x)
  File "/usr/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.5/pickle.py", line 562, in save_tuple
    save(element)
  File "/usr/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.5/pickle.py", line 562, in save_tuple
    save(element)
  File "/usr/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.5/pickle.py", line 748, in save_global
    (obj, module, name))
pickle.PicklingError: Can't pickle <function bar at 0xb753fe2c>: it's not found as __main__.bar

有什么解决办法吗?也许我需要限制用户可以添加为回调的函数类型?

谢谢,
乔纳森

最佳答案

不要尝试 pickle Deferreds。 Twisted 不支持它。即使您设法构建了一些看起来可行的东西(而且它并非完全不可能),Twisted 的更高版本可能会破坏您所有已保存的状态。

Deferreds 用于控制代码中的事件流。它们不是用于存储应用程序状态。如果您想保留您的应用程序状态,请将它与任何 Deferred 分开并序列化只是它。

执行此操作时,您可能还想避免使用 pickle 作为序列化格式。 Pickle 不是存储数据的好方法。它是一种高度复杂的格式,对 Python 版本和库版本的变化非常敏感。它无法定义模式,因此您永远无法真正确定正在序列化的内容或已序列化的内容。很难单独检查 pickle 和加载它,所以如果它曾经中断(如果你决定重命名一个你已经 pickle 过的实例的类,它就会),恢复数据是一个主要的麻烦。

关于python - 如何 pickle 回调链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4831178/

相关文章:

python - 使用 MSN 协议(protocol)运行 twins.words 示例时出现异常

python - 我怎样才能完整地挑选一个类(class)?

Python Pickle 调用构造函数

python - 如何使用属性装饰器设置属性?

python - 对 namedtuple 类进行自定义排序

python - 扭曲多个并发或异步流

python - SklearnClassifier 对象没有属性 _vectorizer

python - LinearSVC 中参数 class_weight 的最佳值是多少?

python - 在mysql中获取自动递增的行ID的时间复杂度

python - Socket.IO 与 Twisted