Как запустить функцию в потоке и далее и пользоваться данными, которые она возвращает?

Всем привет. Столкнулась с проблемой. Есть две функции. Одна отдает список статей, и на основе этих статей идет передача в другую функцию каждой из статей.

class get_list(Theared):
    def __init__(self):
        self.list = []
    def run(self):
        #получени статьи
        #list - массив со статьями
        self.list.append(list)
    def __iter__(self):
        return iter(self.list)
     

class read_list(Theared):
    def __init__(self, p_list):
        Thread.__init__(self)
        self.list = p_list
        self.start()
    def run(self):
        #идет работа со статьей.

if __name__=="__main__":
    i=1
    while i>0:
        finallList = get_list()
        if finallList :
            for one_list in finallList:
                read_list(one_list)
                i=i+1

Но проблема в том , что мне нужно проверять наличие статей например каждые 5 сек, и параллельно должна отрабатывать функция read_list. Пыталась сделать тоже через класс с Thread функцию get_list, но тогда скрипт падает в ошибку

TypeError: 'get_list' object is not iterable

Есть у кого-то идея как сделать ?


Ответы (2 шт):

Автор решения: ganz

Рекомендую использовать модуль queue

import queue
q=queue.Queue(2)
q.empty()
#True
q.full()
#False
q.put(1)
q.get()
#1

Который отлично сочетается с асинхронными вызовами

→ Ссылка
Автор решения: Roman Konoval

Я понял задачу так, что нужно чтоб:

  1. один поток (в примере ниже это ListProducer) генерировал значения
  2. главный поток итерирует по списку ожидая, если значений нет
  3. для каждого значения, запускается отдельный поток (в примере ItemConsumer) для его обработки

Вот код:

from time import sleep
from queue import Empty, Queue
from threading import Thread

class ListProducer(Thread):
    def __init__(self):
        super(ListProducer, self).__init__()
        self.queue = Queue()
        self.stop = False
        self.start()

    def run(self):
        for i in range(5):
            self.queue.put(i)
            print(f"producer: creating {i}")
            sleep(0.5)
        self.stop = True
        print("producer: done")

    def __iter__(self):
        while not self.stop:
            try:
                yield self.queue.get(timeout=0.1)
            except Empty:
                pass


class ItemConsumer(Thread):
    def __init__(self, item):
        super(ItemConsumer, self).__init__()
        self.item = item
        self.start()

    def run(self):
        print(f"consumer: processing {self.item}")
        sleep(1)
        print(f"consumer: processed {self.item}")


if __name__ == '__main__':
    producer = ListProducer()
    for item in producer:
        ItemConsumer(item)
    print("main: done")
→ Ссылка