Python: Concurrent.Futures Ошибка [TypeError: объект 'NoneType' не вызывается] - PullRequest
0 голосов
/ 25 июня 2018

Итак, мне удалось настроить asyncio / API Google CSE для совместной работы .... Когда я запускаю свой код в PyCharm, я могу распечатать свои результаты. Однако в самом конце напечатанного материала находится ошибка «Ошибка типа: объект NoneType не вызывается».

Я подозреваю, что это как-то связано с моим списком и, возможно, с циклом, пытающимся найти другой термин, хотя я в конце списка ...

Также .. это мой первый пост с вопросами, так что не стесняйтесь предлагать, как лучше задавать вопросы

Мысли

searchterms = ['cheese',
    'hippos',
    'whales',
    'beluga']

async def sendQueries(queries, deposit=list()):
    with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
        loop = asyncio.get_event_loop()
        futures = [
            loop.run_in_executor(
                executor,
                searching(queries)
            )
        ]
        for response in await asyncio.gather(*futures):
            deposit.append(response.json())
        return deposit

def running():
     loop = asyncio.get_event_loop()
     loop.run_until_complete(loop.create_task(sendQueries(searchterms)))
     loop.close()

print(running())
print(str(time.time() - x))

Моя ошибка может быть прослежена до "для ответа в await asyncio.gather (* futures):"

Для справки, поиск (запросы) - это просто функция для моего вызова Google CSE API.

1 Ответ

0 голосов
/ 25 июня 2018

Проблема в вызове run_in_executor:

    futures = [
        loop.run_in_executor(
            executor,
            searching(queries)
        )
    ]

run_in_executor принимает функцию для выполнения.Код не передает ему функцию, он вызывает функцию, searching и передает run_in_executor возвращаемое значение этого вызова.Это имеет два последствия:

  1. код не работает должным образом - он вызывает поиск один за другим, а не параллельно;

  2. отображает ошибку, сообщающую о попытке run_in_executor вызвать возвращаемое значение None searching(...).Смущает, что ошибка возникает только позже, когда ожидается ожидание фьючерса, возвращенного run_in_executor, когда все поиски фактически завершатся.

Правильный способ вызова run_in_executor будетбыть что-то вроде:

    futures = [
        loop.run_in_executor(executor, searching, queries)
    ]

Обратите внимание, что функция searching теперь только упоминается вместо используется .

Кроме того, если вытолько используете asyncio для вызова синхронных вызовов в run_in_executor, вы не пользуетесь его преимуществами.Вы можете получить тот же эффект, используя инструменты на основе потоков из concurrent.futures напрямую, но без необходимости настраивать всю программу в асинхронном режиме.run_in_executor предназначен для экономного использования, либо для периодического взаимодействия с унаследованными API-интерфейсами, которые не предоставляют асинхронный интерфейс, либо для кода с интенсивным использованием ЦП, который не может быть осмысленно преобразован в сопрограммы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...