等待没有循环Python的条件

Posted

技术标签:

【中文标题】等待没有循环Python的条件【英文标题】:Waiting for condition without loop Python 【发布时间】:2017-01-01 12:57:40 【问题描述】:

我刚刚创建了一个脚本,该脚本从特定 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。

【问题讨论】:

检查 API 是否有“等待完成”方法或回调等。也许您甚至可以以阻塞直到完成的方式调用您想要使用的功能。 除非您使用的 API 提供了更好的方法,否则不会。如果没有 API 的详细信息,我们基本上只能告诉您这些。 【参考方案1】:

而是使用事件,而不是轮询。如何在 Python 中实现事件有很多选择。有一个讨论here already on stack overflow。

这是一个使用 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')

但是接受的答案中的期货也很整洁。取决于你的船是什么。

【讨论】:

要回答所写问题,您必须解释当您无法控制通常会触发事件的代码部分时如何使用事件。跨度> 没有人有时间做那个【参考方案2】:

虽然如您所说,这篇文章不再具有任何相关性,但它是一个肥皂 API。但是我把工作放进去,所以无论如何我都会发布它。 :)

回答你的问题。我没有看到比轮询(也就是一遍又一遍地循环)更有效的方法


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

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

import time

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

expensive_operation(lambda x:print("Done", x))

如您所见,操作完成后将立即打印消息“Done 6”。

你可以用 Future-objects 重写它。

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

【讨论】:

以上是关于等待没有循环Python的条件的主要内容,如果未能解决你的问题,请参考以下文章

等待条件的空循环(忙等待)

javascript:循环中如何等待方法完成了再继续?

循环重复

我的 for 循环没有根据条件删除数组中的项目? Python [重复]

python的用户输入和while循环

有没有办法在 Python (3) for 循环中执行条件?