0

我正在尝试pyutilib.workflow使用 python 2.7 来腌制(使用 dill 扩展名)一个工作流对象。这里的最终目标是能够将这些工作流对象插入到 MongoDB 数据库中,并在需要时从另一端拉出:

from pyutilib import workflow
import testworkflow
from bson.binary import Binary
import pickle
import dill
import weakref

A = testworkflow.testTask()
w = workflow.Workflow()
w.add(A)

with open('w.dill', 'wb') as f:
    scriptbytes = dill.dump(w, f)
script.close()

testworkflow.py只包含testTask(),其写法如下:

import pyutilib.workflow

class testTask(pyutilib.workflow.Task):

    def __init__(self, *args, **kwds):
        pyutilib.workflow.Task.__init__(self, *args, **kwds)
        self.inputs.declare('x')
        self.inputs.declare('y')
        self.outputs.declare('z')

    def execute(self):
        self.z = self.x + self.y

但是当我尝试执行它来序列化工作流对象时,我从pickle.py文件中得到了一个庞大的回溯列表,其最底部只是“AssertionError”。

它似乎有以下问题:

File "/usr/lib/python2.7/pickle.py", line 649, in save_dict
  self._batch_setitems(obj.iteritems())
File "/usr/lib/python2.7/pickle.py", line 681, in _batch_setitems
  save(v)
File "/usr/lib/python2.7/pickle.py", line 286, in save
  f(self, obj) # Call unbound method with explicit self
File "/usr/local/lib/python2.7/dist-packages/dill/dill.py", line 905, in save_weakref
  pickler.save_reduce(_create_weakref, (refobj,), obj=obj)
File "/usr/lib/python2.7/pickle.py", line 405, in save_reduce
  self.memoize(obj)
File "/usr/lib/python2.7/pickle.py", line 244, in memoize
  assert id(obj) not in self.memo

严重的是,上面的回溯块约占总列表的 1%。几个回溯到同一行代码,那么它是一个循环引用问题吗?我对这种类型的项目完全陌生,我已经搜索了所有其他相关问题,但似乎没有一个真的足够相关。

我错过了一些较新的库吗?有一个更好的方法吗?

编辑:根据 Martijn Pieters 的有用评论

酸洗是一个递归过程,这就是为什么您会看到某些行重复的原因。该过程最终回到之前被腌制的对象(self.memo 中的 id(obj) 仅当对象已被处理时才为真)。

那么我怎样才能阻止这种情况被触发呢?为什么酸洗不能自动忽略已经序列化的块作为递归的基本情况?

编辑 2:'dill.detect.trace(true)' 回溯:

T4: <class 'pyutilib.workflow.workflow.Workflow'>
D2: <dict object at 0x7ffff23955c8>
T4: <class 'pyutilib.workflow.port.InputPorts'>
T4: <class 'pyutilib.workflow.port.Port'>
D2: <dict object at 0x7ffff20a9b40>
R1: <weakref at 0x7ffff238aaf8; to 'Workflow' at 0x7ffff2399d90>
F2: <function _create_weakref at 0x7ffff238c410>
D2: <dict object at 0x7ffff20a9e88> 
D2: <dict object at 0x7ffff2395c58>
T4: <class 'argparse.ArgumentParser'>
D2: <dict object at 0x7ffff20a3050>
F2: <function _compile at 0x7ffff7ed81b8>
D2: <dict object at 0x7ffff20a3398>
T4: <class 'argparse._HelpAction'>
D2: <dict object at 0x7ffff20a36e0>
T4: <class 'argparse._ArgumentGroup'>
D2: <dict object at 0x7ffff20a3c58>
D2: <dict object at 0x7ffff20a34b0>
D2: <dict object at 0x7ffff20a3168>
D2: <dict object at 0x7ffff20a3280>
T4: <class 'argparse._StoreFalseAction'>
T4: <class 'argparse._AppendConstAction'>
T4: <class 'argparse._StoreTrueAction'>
T4: <class 'argparse._CountAction'>
T4: <class 'argparse._StoreConstAction'>
T4: <class 'argparse._VersionAction'>
T4: <class 'argparse._StoreAction'>
T4: <class 'argparse._SubParsersAction'>
T4: <class 'argparse._AppendAction'>
D2: <dict object at 0x7ffff20a35c8>
F1: <function identity at 0x7ffff23a1d70>
F2: <function _create_function at 0x7ffff2389e60>
Co: <code object identity at 0x7ffff4c118b0, file      "/usr/lib/python2.7/argparse.py", line 1591>
F2: <function _unmarshal at 0x7ffff2389cf8>
D4: <dict object at 0x7ffff4c1a050>
D2: <dict object at 0x7ffff20abd70>
D2: <dict object at 0x7ffff20a3910>
T4: <class 'argparse.HelpFormatter'>
T4: <class 'pyutilib.workflow.port.OutputPorts'>
D2: <dict object at 0x7ffff20a3b40>
D2: <dict object at 0x7ffff20ab050>
D2: <dict object at 0x7ffff2395d70>
D2: <dict object at 0x7ffff20a5050>
D2: <dict object at 0x7ffff2395e88>
T4: <class 'pyutilib.workflow.task.EmptyTask'>
D2: <dict object at 0x7ffff20a7398>
D2: <dict object at 0x7ffff20ab280>
R1: <weakref at 0x7ffff238aba8; to 'EmptyTask' at 0x7ffff20a6290>
T4: <class 'pyutilib.workflow.connector.DirectConnector'>
D2: <dict object at 0x7ffff20ab4b0>
D2: <dict object at 0x7ffff2395b40>
R1: <weakref at 0x7ffff238aaa0; to 'testTask' at 0x7ffff23999d0>
T4: <class 'testworkflow.testTask'>
D2: <dict object at 0x7ffff2398d70>
D2: <dict object at 0x7ffff2395a28>
R1: <weakref at 0x7ffff238aaa0; to 'testTask' at 0x7ffff23999d0>
D2: <dict object at 0x7ffff20a9d70>
D2: <dict object at 0x7ffff20a97f8>
R1: <weakref at 0x7ffff238ab50; to 'EmptyTask' at 0x7ffff2399fd0>
D2: <dict object at 0x7ffff20a5168>
D2: <dict object at 0x7ffff20a5280>
R1: <weakref at 0x7ffff238ab50; to 'EmptyTask' at 0x7ffff2399fd0>
D2: <dict object at 0x7ffff20a55c8>
D2: <dict object at 0x7ffff20a5910>
D2: <dict object at 0x7ffff20a5c58>
D2: <dict object at 0x7ffff20a7280>
D2: <dict object at 0x7ffff20a5a28>
D2: <dict object at 0x7ffff20a56e0>
D2: <dict object at 0x7ffff20a57f8>
D2: <dict object at 0x7ffff20a5b40>
F1: <function identity at 0x7ffff23a1de8>
D4: <dict object at 0x7ffff4c1a050>
D2: <dict object at 0x7ffff20b4280>
D2: <dict object at 0x7ffff20a5e88>
D2: <dict object at 0x7ffff20a7168>
D2: <dict object at 0x7ffff20a9c58>
D2: <dict object at 0x7ffff20ab168>
D2: <dict object at 0x7ffff2395910>
D2: <dict object at 0x7ffff20a5398>
D2: <dict object at 0x7ffff20a75c8>
D2: <dict object at 0x7ffff20a54b0>
D2: <dict object at 0x7ffff20a74b0>
4

0 回答 0