python3 queue.PriorityQueue 变化?

标签 python

我正在将我的应用程序从 py27“移植”到 py33。 在大多数情况下,这是非常微不足道的。那就是说我在 py27 和 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 之间发生了什么变化吗?

最佳答案

PriorityQueue 相关的内容没有变化;更改的内容与 dict 有关,更普遍的是对没有自然顺序的对象进行排序。

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

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

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

大多数时候,第一个或第二个元素会有所不同,因此您永远不需要比较第三个元素,所以一切都会好起来的。

但偶尔,您会得到两个这样的值:

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

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

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

Python 2.x 只是做一些随意且无用的事情; Python 3.x 改为引发异常。这记录在 Ordering Comparisons 下在“3.x 的新增功能”文档中:

The ordering comparison operators (<, <=, >=, >) raise a TypeError exception when the operands don’t have a meaningful natural ordering.

所以,在这些情况下你已经遇到了问题,但是 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不处理键,因为“在普通列表上工作的函数”的设计排除了它……

关于python3 queue.PriorityQueue 变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21768493/

相关文章:

python - super(Foo, self) 和 super(Foo, self.__class__) 的区别?

python 3,递归,或在return语句中

python - 按对象从 QuerySet 中获取下一个和上一个对象

python - 捕获/返回 python 日志记录的输出消息

python - tzinfo=tzutc() 是否与+00 :00 in python? 相同

python - Pandas 中数据框行中的数据框列

python - 通过套接字将 C 结构读入 python

python - PyMySQL 将值插入表时出错。 - Python

python - 如何使用sqlautocode?

python - 如何将列表追加到 Python 中函数创建的列表中