On Mon, 9 Mar 2009, Nick Craig-Wood wrote: > John O'Hagan <resea...@johnohagan.com> wrote: > > Is there a concise Pythonic way to write a method with a timeout? > > > > I did this: > > > > class Eg(object): > > > > def get_value(self, timeout): > > > > from threading import Timer > > self.flag = True > > > > def flag_off(): > > self.flag = False > > timer = Timer(timeout, flag_off) > > timer.start() > > > > while self.flag: > > #do stuff for a long time to get some value > > if condition: #if we ever get the value > > self.value = value > > break > > > > but it seems hackish to have a special "flag" attribute just to manage > > the timeout within the the method. > > How about something like this > > from threading import Timer > > class Duration(object): > def __init__(self, duration): > self.running = True > self.timer = Timer(duration, self.set_finished) > self.timer.setDaemon(True) > self.timer.start() > def set_finished(self): > self.running = False > def __nonzero__(self): > return self.running
Nifty! Works for threads too because they can have access to the Duration object. I guess it works on a similar principle to my attempt (setting a flag with a timer) but is cleaner by keeping everything inside the method. So my original method would look like this: class ExIt(object): def __init__(self, iter_func, args=None): self.iter_func = iter_func self.args = args self.length = None def get_length(self, timeout=None): """Try to get length of iterator within a time limit""" if self.length is None: from threading import Thread, Timer timer=Duration(timeout) def count(): gen = self.iter_func(self.args) length = 0 while timer: try: gen.next() length += 1 except StopIteration: self.length = length break getlen = Thread(target=count) getlen.setDaemon(True) getlen.start() Which does exactly what I want: runs a time-consuming task in the background and can optionally time it out. In fact that's so handy, I think it would be nice if there was a standard timer object which is True while running, then False. Or maybe there is? Thanks, John -- http://mail.python.org/mailman/listinfo/python-list