如果以下功能在达到超时之前成功或不成功,您能否建议我返回客户端的好方法?
def until_true(func, condition, timeout):
s = 0.05
t = 0
while t <= timeout:
result = func()
if condition(result):
return t, result
time.sleep(s)
t = t + s
return result
使用当前实现,您可以通过检查返回值的len来测试它是否失败,这非常难看。如果函数成功,我还希望返回结果和函数成功所花费的时间。如果失败了,我希望只返回结果。
答案 0 :(得分:2)
将您的第一个返回值作为 sentinel 检查是否成功。那是
return (True, t, result)
虽然在主叫方接受它,但将其设为success, others, others2 = until_true(..)
,以便您可以测试if success
...
同样,对于失败的部分,您可以
return (False, result)
答案 1 :(得分:2)
更加pythonic的方式是使用exceptions:
class TimeoutException(Exception):
def __init__(self, result):
self.result = result
def until_true(func, condition, timeout):
[...]
raise TimeoutException(result)
try:
time_spent, result = until_true([...])
except TimeoutException as exc:
result = exc.result
答案 2 :(得分:0)
在python中报告错误条件的典型pythonic方法是通过异常而不是返回值。在这种情况下,你仍然想要返回一些东西,所以解决方案变得不那么明确了。不过,你可能想要使用这样的东西(未经测试):
class Timeout(Exception): pass
def until_true(func, condition=bool, timeout=1.0, interval=0.05):
t = 0
while t <= timeout:
result = func()
if condition(result):
return t, result
time.sleep(interval)
t += interval
raise Timeout(result)
try:
t, result = until_true(func)
except Timeout as err:
print "Oh no, timed out! But got result " + str(err.message)
我认为如果通常不应该发生超时,这种方法会更好,并且需要采取一些特殊措施。否则,一个简单的方法是简单地返回t
,结果在任何情况下,让调用者检查t
是否大于超时,或者在超时时为t
返回一些特殊值,甚至使用第三个返回值,如另一个答案。
(顺便说一下,你的逻辑假定func
或condition
没有时间执行。如果它们很耗时,until_true
最终会运行超过你的超时因为你只计算睡觉的时间。更好的方法是使用time.time()
或类似方法来检查实际的经过时间。)