Опасность работать неумышленный Удаляет (или вставляет, или обновления) всегда находится на моем уме.
я всегда добавляю, "где 1=2" после них, пока я не готов нажать на курок.
Если вас не волнует порядок, в котором обрабатываются элементы, я бы попробовал подкласс Очередь
, которая использует набор
внутри:
class SetQueue(Queue):
def _init(self, maxsize):
self.maxsize = maxsize
self.queue = set()
def _put(self, item):
self.queue.add(item)
def _get(self):
return self.queue.pop()
Как указал Пол МакГуайр, это позволит добавить повторяющийся элемент после того, как он был удален из набора «подлежащих обработке» и еще не добавлен в «обработанный» набор. Чтобы решить эту проблему, вы можете сохранить оба набора в экземпляре Queue
, но поскольку вы используете больший набор для проверки того, был ли элемент обработан, вы можете также вернуться в очередь
, который будет правильно упорядочивать запросы.
class SetQueue(Queue):
def _init(self, maxsize):
Queue._init(self, maxsize)
self.all_items = set()
def _put(self, item):
if item not in self.all_items:
Queue._put(self, item)
self.all_items.add(item)
Преимущество этого, в отличие от использования набора отдельно, заключается в том, что методы Queue
являются потокобезопасными, так что вы не
SQLite настолько прост в использовании и идеально подходит ... просто предложение.
вместо «массив уже посещенных страниц» сделать «массив уже добавленных в очередь страниц»
Способ, которым я решил это (на самом деле я сделал это на Scala, а не на Python), заключался в использовании как Set, так и Queue, только добавляя ссылки в очередь (и устанавливая), если они не уже существуют в наборе.
И набор, и очередь были инкапсулированы в один поток, предоставляя только интерфейс, похожий на очередь, для потоков-потребителей.
Редактировать: кто-то другой предложил SQLite, и это тоже то, что я рассматриваю , если набор посещаемых URL-адресов необходимо увеличить. (В настоящее время каждое сканирование занимает всего несколько сотен страниц, поэтому легко умещается в памяти.) Но база данных также может быть инкапсулирована внутри самого набора, поэтому потоки-потребители не должны знать об этом.
Также вместо набора вы можете попробовать использовать словарь. Операции над наборами, когда они большие, обычно выполняются довольно медленно, тогда как поиск по словарю - это хорошо и быстро.
My 2c.
Зачем использовать только массив (в идеале, словарь был бы еще лучше) для фильтрации уже посещенных вами вещей? Добавляйте вещи в свой массив / словарь, как только вы ставите их в очередь, и только добавляйте их в очередь, если их еще нет в array / dict. Тогда у вас есть 3 простые отдельные вещи: