6

我有一个使用队列对象列表的类。我需要腌制这个类,包括保存在队列对象中的信息。例如:

import Queue
import pickle

class QueueTest(object):
    def __init__(self):
        self.queueList = []
    def addQueue(self):
        q = Queue.Queue()
        q.put('test')
        self.queueList.append(q)


obj = QueueTest()
obj.addQueue()

with open('pickelTest.dat','w') as outf:
    pickle.dump(obj,outf)

返回错误

raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle lock objects

是否有解决方法来腌制 Queue 对象?

4

2 回答 2

11

我建议用 替换你的Queue.Queue使用collections.deque。该类Queue旨在用于线程之间的同步通信,因此在用作常规数据结构时会产生一些不必要的开销。collections.deque是一个更快的选择。(“deque”这个名字读作“deck”,意思是“双端队列”。)

该类deque确实具有与Queue类型不同的 API,但在它们之间进行转换应该很容易。使用deque.append代替Queue.putdeque.popleft代替q.get()(或appendleftpop,如果你想去另一个方向)。而不是调用Queue.empty,只需使用一个deque实例作为布尔值(就像你测试一个空列表一样)。

deque实例是可腌制的:

>>> import collections, pickle
>>> q = collections.deque(["test"])
>>> pickle.dumps(q)
b'\x80\x03ccollections\ndeque\nq\x00]q\x01X\x04\x00\x00\x00testq\x02a\x85q\x03Rq\x04.'
于 2013-05-25T21:56:10.580 回答
3

正如您对@Blckknght 所评论的那样,您不需要Queue.Queue. 因此,只需使用collections.deque该类Queue.Queue将自身用作底层队列数据结构。您将不得不使用.appendleft来模拟 FIFOQueue.put.pop模拟Queue.get

于 2013-05-25T21:48:52.303 回答