Python queue 类 实现元素唯一性的方法

queue 是 python 内置的轻量级的多生产者、多消费者消息队列模块,小巧玲珑,安全好用。

queue 模块好是好,就是入队时不支持检测元素的唯一性。比如我的爬虫有一组URL,或者ID,重复的数据就没必要再放入队列。如果在多线程中直接操作,过程不可控,很容易出问题。

查询资料,CSDN 上有解决方案(原文点这),通过修改 queue 模块的源代码,在put方法中增加一个unique参数,依据此参数是否为 True ,在底层的 deque 中判断将要加入的元素是否存在,以此实现检测元素唯一性的功能。

试之,可行。

具体过程如下:

首先找到 python 内置函数 queue 模块的位置:

import sys
sys.path

位置如下:

/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7

通过以上路径,找到 queue.py 文件 ,修改以下代码:

    def put(self, item, block=True, timeout=None, unique=False):
        
        with self.not_full:
            # ----- 以下三行为新增代码 -----#
            if unique:
                if item in self.queue:
                    return
            # ----- 新增代码结束 -----#

            if self.maxsize > 0:
                if not block:
                    if self._qsize() >= self.maxsize:
                        raise Full
                elif timeout is None:
                    while self._qsize() >= self.maxsize:
                        self.not_full.wait()
                elif timeout < 0:
                    raise ValueError("'timeout' must be a non-negative number")
                else:
                    endtime = time() + timeout
                    while self._qsize() >= self.maxsize:
                        remaining = endtime - time()
                        if remaining <= 0.0:
                            raise Full
                        self.not_full.wait(remaining)
            self._put(item)
            self.unfinished_tasks += 1
            self.not_empty.notify()

完成。