A better way to timeout a class method?

John O'Hagan research at johnohagan.com
Mon Mar 9 11:31:40 EDT 2009


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.

Any comments appreciated.

Regards,
John

P.S. A more detailed but non-essential example:

The use case is an iterator class which has a method to get the length of an 
instance, and does this as a thread so that other operations can proceed. It 
is subject to a timeout as the iterator may be arbitrarily long.

Showing just the relevant method:

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:

            self.flag = True
            from threading  import Thread
            def count():
                gen = self.iter_func(self.args)
                length = 0
                while self.flag:
                    try:
                        gen.next()
                        length += 1
                    except StopIteration:
                        self.length = length
                        break
            getlen = Thread(target=count)
            getlen.setDaemon(True)             

            if timeout:
                from threading  import Timer
                def flag_off():
                    self.flag = False
                timer = Timer(timeout, flag_off)
                timer.start()
                
            getlen.start()

Any comments on this also appreciated.



More information about the Python-list mailing list