Python: Concurrent.Futures Error [TypeError: 'NoneType' object is not callable]

Python: Concurrent.Futures Error [TypeError: 'NoneType' object is not callable]

所以我设法让 asyncio / Google CSE API 一起工作....当我 运行 我的代码在 PyCharm 上时,我能够打印出我的结果。但是,打印内容的最后是错误 "TypeError: 'NoneType' object is not callable".

我怀疑它与我的列表有关,也许循环试图搜索另一个术语,即使我在列表的末尾...

此外..这是我的第一个问题post所以请随时提供有关如何更好地提问的建议

想法?

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))

我的错误可以追溯到"for response in await asyncio.gather(*futures):"

供您参考,搜索(查询)只是我的 Google CSE API 调用的功能。

问题出在对 run_in_executor 的调用中:

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

run_in_executor 接受要执行的函数。该代码没有向它传递一个函数,它 调用 一个函数 searching,并向 run_in_executor 传递该调用的 return 值。这有两个后果:

  1. 代码没有按预期工作 - 它一个接一个地调用搜索,而不是并行;

  2. 它显示一个错误,抱怨 run_in_executor 试图调用 searching(...)None return 值。令人困惑的是,错误只是在稍后等待 run_in_executor 编辑的 return 时出现,到那时所有搜索实际上已经完成。

调用 run_in_executor 的正确方法应该是这样的:

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

请注意 searching 函数现在如何只 提及 而不是 使用

此外,如果您仅使用 asyncio 来调用 run_in_executor 中的同步调用,您并没有真正从它的使用中受益。您可以直接使用 concurrent.futures 中基于线程的工具获得相同的效果,但无需将整个程序调整为 asyncio。 run_in_executor 应谨慎使用,用于偶尔与不提供异步前端的遗留 API 交互,或用于无法有意义地转换为协程的 CPU-heavy 代码。

我也遇到了 executor.submit() 相同的错误

# not work
futures.append(executor.submit(myfunc(arg1, arg2)))

# works
futures.append(executor.submit(myfunc, arg1, arg2))

谢谢大家,