python3 queue.PriorityQueue有变化吗?

时间:2014-02-14 00:22:09

标签: python

我正在将我的应用程序从py27“移植”到py33。 在大多数情况下,这是非常微不足道的。那说py27和amp;之间有一个非常奇怪的区别。 py33

我基本上有两个线程,他们通过队列进行通信。 发送的数据类型如下:

TX_Queue.put((3,'SOME_TAG',{some:type,of:data})

即优先级,命令,数据

这在py27中运行得非常好,但是现在大部分转换为py33已经完成了我不时会得到一个奇怪的例外:

return heappop(self.queue)
TypeError: unorderable types: dict() < dict()

任何想法是关于PriorityQueues这是py27和py3之间的变化是什么?

1 个答案:

答案 0 :(得分:8)

PriorityQueue s无关;改变的内容与dict有关,更常见的是对没有自然排序的对象进行排序。

问题是你正在尝试对包含dicts的两个元组进行排序,如下所示:

(3, 'SOME_TAG', {'some': 'type', 'of': 'data'})

元组按字典顺序比较 - 也就是说,它们首先比较第一个元素,如果它们相等,则尝试第二个元素,如果它们相等,则尝试第三个元素,依此类推。

大多数情况下,第一个或第二个元素会有所不同,所以你不需要比较第三个元素,所以一切都会好的。

但偶尔会有两个这样的值:

(3, 'SOME_TAG', {'some': 'type', 'of': 'data'})
(3, 'SOME_TAG', {'some': 'othertype', 'with': 'differentdata'})

然后,它需要比较两个dicts来决定哪个元组更少。

这是一件毫无意义的事情。词典的项目本质上是无序的,那么你如何决定哪一个比另一个少呢?事实上,即使 是项目的固定且可预测的元素,您在此期望的规则是什么?第一个减少是因为'of' < 'with'吗?或更大,因为'other type' < 'type'?还是...?

Python 2.x只做一些随意而无用的事情; Python 3.x反而引发异常。这在Ordering Comparisons的“3.x中的新内容”文档中记录:

  

当操作数没有有意义的自然时,排序比较运算符(<<=>=>)会引发TypeError异常排序。

所以,你在这些情况下已经遇到了问题,但是Python 2.x通过偶尔默默地做一些无用的事情来隐藏问题,而3.x使问题显而易见。


那么,解决方案是什么?那么,你想要发生什么?我的猜测是你实际上想要排序第一个元素,忽略其他元素。在这种情况下,你在Python 2.x中自动获得接近的东西,而你可能没有注意到它有时会以不可预测的方式不稳定。但如果您真的想要这种行为,那么在两个版本中,您都必须自己编写。

不幸的是,与Python中大多数与排序相关的函数和对象不同,PriorityQueue不使用key函数。*这意味着您必须手动“装饰 - 排序 - 未装饰”。但这并不难。例如:

class TupleSortingOn0(tuple):
    def __lt__(self, rhs):
        return self[0] < rhs[0]
    def __gt__(self, rhs):
        return self[0] > rhs[0]
    def __le__(self, rhs):
        return self[0] <= rhs[0]
    def __ge__(self, rhs):
        return self[0] >= rhs[0]

然后你可以这样做:

TX_Queue.put(TupleSortingOn0(3,'SOME_TAG',{some:type,of:data}))

*因为它使用了heapq,并且heapq无法处理密钥,因为“正常列表中运行的函数”的设计排除了它...