Python 在没有循环的情况下等待条件

Python 在没有循环的情况下等待条件,python,while-loop,sleep,Python,While Loop,Sleep,我刚刚创建了一个脚本,它从特定的API触发一个报告,然后将其加载到我的数据库中。 我已经构建了一些可以工作的东西,但我想知道是否有更“精确”或更高效的东西,而不需要让我的脚本反复循环 我当前的脚本如下所示: import time retry=1 trigger_report(report_id) while report_id.status() != 'Complete': time.sleep(retry * 1.3) retry =+ 1 load_report(re

我刚刚创建了一个脚本,它从特定的API触发一个报告,然后将其加载到我的数据库中。 我已经构建了一些可以工作的东西,但我想知道是否有更“精确”或更高效的东西,而不需要让我的脚本反复循环

我当前的脚本如下所示:

import time

retry=1
trigger_report(report_id)

while report_id.status() != 'Complete':
    time.sleep(retry * 1.3)
    retry =+ 1

load_report(report_id)
编辑:

API不提供任何等待完成方法,它最多只提供一个返回作业状态的端点。
它是一个SOAP API。

而是使用事件,而不是轮询。关于如何在Python中实现事件,有很多选项。进行了一次讨论

下面是一个使用zope.event和事件处理程序的合成示例

import zope.event
import time


def trigger_report(report_id):
    #do expensive operation like SOAP call
    print('start expensive operation')
    time.sleep(5)
    print('5 seconds later...')
    zope.event.notify('Success') #triggers 'replied' function

def replied(event): #this is the event handler
    #event contains the text 'Success'
    print(event)

def calling_function():
    zope.event.subscribers.append(replied)
    trigger_report('1')

但在公认的答案中,未来也是整洁的。这取决于什么能让你的船漂浮。

虽然这篇文章不再像你说的那样有任何关联,但它是一个soap API。但是我把工作放进去了,所以我还是会把它贴出来的。:)

回答你的问题。我看不到比轮询(又称循环)更有效的方法了


有多种方法可以做到这一点

第一种方法是实现某种回调,该回调在任务完成时触发。它看起来像这样:

import time

def expensive_operation(callback):
    time.sleep(20)
    callback(6)

expensive_operation(lambda x:print("Done", x))
如您所见,操作完成后将立即打印消息“
Done 6

您可以用将来的对象重写它

from concurrent.futures import Future
import threading
import time

def expensive_operation_impl():
    time.sleep(20)
    return 6

def expensive_operation():
    fut = Future()
    def _op_wrapper():
        try:
            result = expensive_operation_impl()
        except Exception as e:
            fut.set_exception(e)
        else:
            fut.set_result(result)

    thr = threading.Thread(target=_op_wrapper)
    thr.start()

    return fut

future = expensive_operation()
print(future.result())               # Will block until the operation is done.
因为这看起来很复杂,所以有一些高级函数为您实现线程调度

import concurrent.futures import ThreadPoolExecutor
import time

def expensive_operation():
    time.sleep(20)
    return 6

executor = ThreadPoolExecutor(1)
future = executor.submit(expensive_operation)

print(future.result())

检查API中的“等待完成”方法或回调等。也许你甚至可以调用你想使用的功能,直到完成为止。除非你使用的API提供了更好的方法,否则不行。没有API的详细信息,这基本上是我们能告诉你的全部。作为对问题的书面回答,你必须解释当你不能控制通常会触发事件的代码部分时如何使用事件。难道没有人有时间吗