python3 queue.PriorityQueue有变化吗?

Nai*_*aib 3 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()
Run Code Online (Sandbox Code Playgroud)

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

aba*_*ert 9

没有任何改变与PriorityQueues 有关; 更改的内容与dict排序没有自然排序的对象有关,更常见的是.

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

(3, 'SOME_TAG', {'some': 'type', 'of': 'data'})
Run Code Online (Sandbox Code Playgroud)

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

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

但有时,你会得到两个这样的值:

(3, 'SOME_TAG', {'some': 'type', 'of': 'data'})
(3, 'SOME_TAG', {'some': 'othertype', 'with': 'differentdata'})
Run Code Online (Sandbox Code Playgroud)

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

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

Python 2.x只做一些随意而无用的事情; Python 3.x反而引发异常.这在"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]
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

TX_Queue.put(TupleSortingOn0(3,'SOME_TAG',{some:type,of:data}))
Run Code Online (Sandbox Code Playgroud)

*因为它使用heapq了封面,并且heapq不处理密钥,因为"在正常列表上工作的功能"的设计排除了它...