【问题标题】:Why is len() not implemented for Queues?为什么队列没有实现 len()?
【发布时间】:2017-12-01 01:35:35
【问题描述】:

内置函数len() (https://docs.python.org/3/library/functions.html#len) 返回“对象的长度(项目数)”,但对于queue.Queue(@987654322 @)。 相反,queue.Queue 有一个 qsize() 方法,它返回队列的大致大小,当它明显有长度时;您可以在构造函数中指定 Queue 的最大长度。类似的collections.deque 确实适用于len

queue.Queue 不使用常见的len() 的原因是什么?或者:如果qsize 改为__len__ 来启用len() 功能会出现什么问题?

【问题讨论】:

  • 可能是因为人们希望len 返回一个准确的值,而不是一个近似值。而且它应该很快。要实现准确的__len__,必须暂时锁定队列以防止添加和删除,这会影响性能。

标签: python multithreading queue language-design


【解决方案1】:

len() 没有为queue.Queue 实现,因为这将是一个“令人讨厌的麻烦”:只有专家甚至应该考虑使用它,但一个“友好的名称”会鼓励非专家使用它。

与大多数序列类型(如 listdeque)不同,queue.Queue 专门打算用于多线程上下文中(multiprocessing 模块的队列也是如此类型)。虽然Queue 中的项目数在任何特定时间肯定都有一个确定的值,但用户代码不可能找出该值是什么:在对.qsize() 的调用返回和您的代码可以 查看返回值,任何数量的其他线程(或进程,在multiprocessing 的情况下)可能已经对队列的内容进行了任何数量的更改。

因此,关于.qsize() 返回的值,唯一可以说的是Queue 某个时间中有很多值过去。当您可以使用返回的值时,它可能包含任意更多(或更少)的值。

当然,如果您只运行一个线程,情况就不是这样了 - 但您无需为 Queue 的实现复杂性付费(改用 listdeque)。

【讨论】:

  • 那么为什么要为队列实现empty()full()
  • 如果我写了empty()full(),它们就不会实现它们;-) 在早期,各种可选的timeout= 参数不存在,full()empty() 在循环中被用作 概率 噱头,以正确猜测 .put().get() 是否“可能”成功。使用它们的代码(例如使用 qsize() 的代码)通常不会出现时序错误。
  • 我不是专家,因此对我来说,一个简单且最不令人惊讶的len() 听起来比过度思考qsize() 更好。可以在帮助消息中解释len 的细节和可能的不准确之处,这对于程序员来说应该足够了。
  • 我不明白。 len 函数是可覆盖的:“The len() function will use the __len__ method if present to query your object for its length.” 为什么不将 __len__ 别名为 qsize?然后你得到完全相同的属性。 if o.qsize() > 0: o.get() 并不比 if len(o) > 0: o.get() 更可靠或更不可靠。
猜你喜欢
  • 1970-01-01
  • 2013-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-27
  • 2021-12-31
  • 2011-03-20
相关资源
最近更新 更多