Python中的Pickle Queue对象

10

我有一个使用队列对象列表的类。我需要将这个类进行pickle处理,包括保存在队列对象中的信息。例如:

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

有没有绕过pickle队列对象的方法?

1
你需要 Queue.Queue 的同步特性吗?也就是说,你是在使用队列来在不同的线程之间进行通信,还是只是作为一个普通的数据结构? - Blckknght
只是一个普通的数据结构。 - Joel Green
2个回答

14

我建议将您使用Queue.Queue的地方替换为collections.dequeQueue类旨在用于线程间同步通信,因此在作为常规数据结构时会有一些不必要的开销。 collections.deque 是更快的替代方法。(“deque”的名称发音为“deck”,意思为“双端队列”)。

deque类具有与Queue类型不同的API,但在它们之间进行转换应该相当容易。使用deque.append替换Queue.put,并使用deque.popleft替换q.get()(或者如果您想采用另一种方式,则可以使用appendleftpop)。而不是调用Queue.empty,只需将deque实例用作布尔值(就像测试空列表一样)。

deque实例是可pickle化的(即可进行序列化):

>>> 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.'

4

如您对@Blckknght所说,您不需要Queue.Queue的同步功能。因此,只需使用collections.deque作为底层队列数据结构,这是Queue.Queue类自身使用的。您将需要使用.appendleft来模拟FIFO Queue.put.pop来模拟Queue.get


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接